我目前正在使用 Windows API 开发 Windows 桌面应用程序。我对 API 还很陌生,所以我正在使用 Visual Studio Community 提供的一些可视化帮助进行开发。
结构很简单:我有一个主窗口,其中放置了一些文本框和一个菜单。
如果我像这样创建窗口:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {
MSG msg;
HWND hVentana;
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = cVentana;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = L"MainWindowClass";
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc)) {
MessageBox(NULL, L"Fallo al registrar la clase de ventana.", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
hVentana = CreateWindowEx(0, L"MainWindowClass", L"Emulador", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1600, 900, NULL, NULL, hInst, NULL);
if (!hVentana) {
MessageBox(NULL, L"Fallo al crear la ventana.", L"Error", MB_OK | MB_ICONERROR);
return 0;
}
HMENU hMenu = LoadMenu(hInst, L"IDD_MENU1"); // El menu está definido en resource.rc
SetMenu(hVentana, hMenu);
HWND hTextBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
10, 10, 387, 824, hVentana, NULL, GetModuleHandle(NULL), NULL);
HWND hRamBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
407, 477, 785, 309, hVentana, NULL, GetModuleHandle(NULL), NULL);
HWND hSearchBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
407, 796, 785, 38, hVentana, NULL, GetModuleHandle(NULL), NULL);
HWND hTerminalBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
407, 60, 785, 405, hVentana, NULL, GetModuleHandle(NULL), NULL);
HWND hRegistrosBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY | ES_AUTOVSCROLL | ES_MULTILINE,
1202, 10, 374, 824, hVentana, NULL, GetModuleHandle(NULL), NULL);
ShowWindow(hVentana, cShow);
UpdateWindow(hVentana);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
没问题。
但是,如果我这样做:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {
MSG msg;
HWND hVentana;
hVentana = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, cVentana);
ShowWindow(hVentana, cShow);
UpdateWindow(hVentana);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
显示菜单,但如果我将鼠标悬停在任何项目上,则不会弹出该项目的选项。
我这里有菜单资源和对话框资源:
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDD_MENU1 MENU
BEGIN
POPUP "Archivo"
BEGIN
MENUITEM "Cargar programa", ID_LOADPROGRAM
MENUITEM "Cargar campaña", ID_LOADCAMPAING
MENUITEM "Salir", ID_EXIT
END
POPUP "Generar"
BEGIN
MENUITEM "Informe de instrucciones", ID_GENERAR_INFORMEDEINSTRUCCIONES
MENUITEM "Archivo RAM", ID_GENERAR_ARCHIVORAM
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG1 DIALOGEX 0, 0, 1600, 900
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_CAPTION | WS_SYSMENU
CAPTION "Emulador"
MENU IDD_MENU1
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
EDITTEXT IDC_TEXTBOX,10,10,387,824,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
EDITTEXT IDC_RAMBOX,407,477,785,309,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
EDITTEXT IDC_SEARCHBOX,407,796,785,38,ES_AUTOHSCROLL | NOT WS_TABSTOP
EDITTEXT IDC_TERMINALBOX,407,60,785,405,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
EDITTEXT IDC_REGISTERSBOX,1202,10,374,824,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | NOT WS_TABSTOP
END
如果资源文件中包含所有对话框就好了,所以如果有其他方法可以制作它,请随时告诉我。
注意:此外,出于任何原因,当我使用第一种形式时,窗口的尺寸是正确的,但如果我使用第二种形式,则窗口比我指定的尺寸大。
使用
CreateDialog()
时,您需要在调用IsDialogMessage()
+TranslateMessage()
之前将DispatchMessage()
添加到消息循环中,例如:
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int cShow) {
MSG msg;
HWND hVentana = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, cVentana);
ShowWindow(hVentana, cShow);
UpdateWindow(hVentana);
while (GetMessage(&msg, NULL, 0, 0)) {
if (!IsDialogMessage(hVentana, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}