Диалог в стиле MFC на WinAPI

285
22 июля 2017, 07:36

Windows 7. Создаю диалог по шаблону с помощью DialogBoxIndirect. Шаблон - массив байт, выдран из exe-шника использующего MFC. Диалог отрисовывается один в один, как в упомянутом exe-шнике, только: 1. кнопки квадратные, 2. рамка вокруг окна жирная (как в калькуляторе или блокноте) 3. titlebar более широкий.

Первую проблему победил с помощью прагмы:

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

Как лечатся оставшиеся 2 проблемы?

Набросал с нуля исходник (платформа x64, UNICODE):

#include<Windows.h>
#include<assert.h>
#include<CommCtrl.h>
#pragma comment(lib, "comctl32.lib")
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#define PASSWORD_ID_LEN 16
#define MAX_PASSWORD_LENGTH 256
#define DIID_ED_MACHINE_ID 0x3e8
#define DIID_ED_PASSWORD 0x3ea
#define DIID_ED_PASSWORD_ID 0x3e9
#define DIID_BT_CREATE_ID 0x3eb
void CreateId(HWND hDlg)
{
  BYTE PasswordID[PASSWORD_ID_LEN];
  char text[MAX_PASSWORD_LENGTH];
  GetDlgItemTextA(hDlg, DIID_ED_PASSWORD, text, MAX_PASSWORD_LENGTH);
  int i = (int)strlen(text);
  if (i)
  {
    _itoa_s(i, (char *)PasswordID, PASSWORD_ID_LEN, 10);
    SetDlgItemTextA(hDlg, DIID_ED_PASSWORD_ID, (LPCSTR)PasswordID);
  }
  else
    SetDlgItemText(hDlg, DIID_ED_PASSWORD_ID, L"");
}
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch (message)
  {
  case WM_INITDIALOG:
  {
    RECT rc;
    GetWindowRect(hDlg, &rc);
    int xPos = (GetSystemMetrics(SM_CXSCREEN) - rc.right) >> 1;
    int yPos = (GetSystemMetrics(SM_CYSCREEN) - rc.bottom) >> 1;
    SetWindowPos(hDlg, 0, xPos, yPos, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
    SetDlgItemText(hDlg, DIID_ED_MACHINE_ID, L"machine id");
    return TRUE;
  }
  case WM_COMMAND:
  {
    int wmId = LOWORD(wParam);
    switch (wmId)
    {
    case DIID_ED_PASSWORD:
    {
      if (HIWORD(wParam) == EN_CHANGE)
        CreateId(hDlg);
      break;
    }
    case IDOK:
    case IDCANCEL:
    {
      EndDialog(hDlg, wmId);
      return TRUE;
    }
    case DIID_BT_CREATE_ID:
      CreateId(hDlg);
      break;
    } // switch (wmId)
    break;
  } // case WM_COMMAND
  } // switch (message)
  return FALSE;
} // LRESULT CALLBACK DlgProc(HWND , UINT , WPARAM , LPARAM )
int APIENTRY wWinMain(
  _In_ HINSTANCE hInstance,
  _In_opt_ HINSTANCE hPrevInstance,
  _In_ LPWSTR    lpCmdLine,
  _In_ int       nCmdShow
)
{
  UNREFERENCED_PARAMETER(hPrevInstance);
  UNREFERENCED_PARAMETER(lpCmdLine);
  INITCOMMONCONTROLSEX icce;
  icce.dwSize = 8;
  icce.dwICC = ICC_WIN95_CLASSES;
  assert(InitCommonControlsEx(&icce));
  // 0x3e8 - Edit с Id.
  // 0x3ea - Edit с паролем.
  // 0x3e9 - Edit с Id пароля.
  // 0x3eb - Button "Создать ID"
  // Этот дамп содержит шаблон диалогового окна. Получен из Иды, при исследовании оригинального MFC приложения.
  const wchar_t caption[] = L"WinApiLikeMfc - тест";
  const BYTE dlg_template1[] = {
    0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xc8, 0x00, 0xc8, 0x90,
    0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x01, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00
  };
  const BYTE dlg_template2[] = {
    0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4d, 0x00,
    0x53, 0x00, 0x20, 0x00, 0x53, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00,
    0x44, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x02, 0x50, 0x07, 0x00, 0x29, 0x00, 0x68, 0x01, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x82, 0x00, 0x12, 0x04, 0x32, 0x04, 0x35, 0x04, 0x34, 0x04, 0x38, 0x04, 0x42, 0x04,
    0x35, 0x04, 0x20, 0x00, 0x3f, 0x04, 0x30, 0x04, 0x40, 0x04, 0x3e, 0x04, 0x3b, 0x04, 0x4c, 0x04,
    0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x81, 0x50, 0x11, 0x00, 0x37, 0x00, 0x5e, 0x01, 0x0e, 0x00, 0xea, 0x03, 0x00, 0x00,
    0xff, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x01, 0x50, 0x3d, 0x01, 0x4c, 0x00, 0x32, 0x00, 0x0e, 0x00, 0xeb, 0x03, 0x00, 0x00,
    0xff, 0xff, 0x80, 0x00, 0x21, 0x04, 0x3e, 0x04, 0x37, 0x04, 0x34, 0x04, 0x30, 0x04, 0x42, 0x04,
    0x4c, 0x04, 0x20, 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x50, 0x3d, 0x01, 0x8c, 0x00, 0x32, 0x00, 0x0e, 0x00,
    0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0x00, 0x12, 0x04, 0x4b, 0x04, 0x45, 0x04, 0x3e, 0x04,
    0x34, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x02, 0x50, 0x07, 0x00, 0x07, 0x00, 0x68, 0x01, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x82, 0x00, 0x49, 0x00, 0x44, 0x00, 0x20, 0x00, 0x3a, 0x04, 0x3e, 0x04, 0x3c, 0x04,
    0x3f, 0x04, 0x4c, 0x04, 0x4e, 0x04, 0x42, 0x04, 0x35, 0x04, 0x40, 0x04, 0x30, 0x04, 0x3a, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x80, 0x50,
    0x11, 0x00, 0x11, 0x00, 0x5e, 0x01, 0x0e, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xff, 0xff, 0x81, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x50,
    0x07, 0x00, 0x5f, 0x00, 0x68, 0x01, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x82, 0x00,
    0x49, 0x00, 0x44, 0x00, 0x20, 0x00, 0x3f, 0x04, 0x30, 0x04, 0x40, 0x04, 0x3e, 0x04, 0x3b, 0x04,
    0x4f, 0x04, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x08, 0x80, 0x50, 0x11, 0x00, 0x69, 0x00, 0x5e, 0x01, 0x0e, 0x00, 0xe9, 0x03, 0x00, 0x00,
    0xff, 0xff, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x00, 0x00, 0x50, 0x07, 0x00, 0x81, 0x00, 0x68, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00 };
  BYTE *pdlg_template = new BYTE[sizeof(dlg_template1) + sizeof(caption) + sizeof(dlg_template2)];
  BYTE *p = pdlg_template;
  memcpy(p, dlg_template1, sizeof(dlg_template1));
  p += sizeof(dlg_template1);
  memcpy(p, caption, sizeof(caption));
  p += sizeof(caption);
  memcpy(p, dlg_template2, sizeof(dlg_template2));
  LRESULT res = DialogBoxIndirect(
    hInstance,
    (LPCDLGTEMPLATE)pdlg_template,
    nullptr,
    DlgProc
  );
  delete[] pdlg_template;
  return res == -1 ? 1 : 0;
} // int APIENTRY wWinMain(_In_ HINSTANCE , _In_opt_ HINSTANCE , _In_ LPWSTR , _In_ int )

Вывод:

"WinApiLikeMfc.exe" (Win32). Загружено "D:\Work\test\WinApiLikeMfc\x64\Debug\WinApiLikeMfc.exe". Символы загружены.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\ntdll.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\kernel32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\KernelBase.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\user32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\gdi32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\lpk.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\usp10.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\msvcrt.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\winsxs\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.18837_none_fa3b1e3d17594757\comctl32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\shlwapi.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\vcruntime140d.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\ucrtbased.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-timezone-l1-1-0.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-file-l2-1-0.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-localization-l1-2-0.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-synch-l1-2-0.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-processthreads-l1-1-1.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\api-ms-win-core-file-l1-2-0.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\imm32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\msctf.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\uxtheme.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\dwmapi.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\advapi32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\sechost.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\rpcrt4.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\ole32.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\cryptbase.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\clbcatq.dll". Невозможно найти или открыть PDB-файл.
"WinApiLikeMfc.exe" (Win32). Загружено "C:\Windows\System32\oleaut32.dll". Невозможно найти или открыть PDB-файл.
Answer 1

Разобрался! Все дело в поле IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion PE заголовка. Если туда записать значение 5, рамка станет тонкой, что логично.

Answer 2

В настройках проекта выбрал Platform Toolset: Visual Studio 2010 (v100), получил окно без рамки =) До этого было: Visual Studio 2017 (v141).

READ ALSO
Codeblocks Ошибка при запуске программы 0xc00000fd

Codeblocks Ошибка при запуске программы 0xc00000fd

Написал трехмерное дерево фенвика на c++, запускаю прогу, она вылетает с кодом ошибки 0xc00000fd, вот код:

239
Передача класса в функцию в c++

Передача класса в функцию в c++

Как нужно передать класс в функцию someFunction(Example), чтоб при её вызове элемент mgrid[3][3] изменился?

141
Определить в Jquery (Обработчик событии) когда создается scrolling прокрутка

Определить в Jquery (Обработчик событии) когда создается scrolling прокрутка

Есть обработчик onscrollСобытие onscroll происходит, когда элемент прокручивается

253