我正在学习C++
,我有一些问题。 msdn的一些研究对我没有帮助。我想在一个应用程序中创建两个窗口。一个窗口 - 带有选项的对话框和另一个用于图形输出这是我使用的代码。但我有一些问题:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow)
{
InitCommonControls();
if(FAILED(DialogWindow_OnCreate(hInstance)))
return 1;
if(FAILED(GraphicWindow_OnCreate(hInstance)))
return 1;
MSG msg;
memset(&msg, 0, sizeof(MSG));
while(msg.message != WM_QUIT)
{
while(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
OnUpdate();
}
GraphicWindow_OnClose();
return 0;
}
创建主窗口(对话框):
HRESULT DialogWindow_OnCreate(HINSTANCE hInst)
{
g_hDialogWindow = CreateDialog(hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, DialogWindow_WndProc);
if(!g_hDialogWindow)
return E_NOTIMPL;
UpdateWindow(g_hDialogWindow);
return S_OK;
}
主窗口proc(对话框):
INT_PTR CALLBACK DialogWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
g_hDialogWindow = hWnd;
// Some init actions ...
return (INT_PTR)TRUE;
}
case WM_COMMAND:
int wmId, wmEvent;
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch(wmEvent)
{
case NULL: // Menu used
{
switch(wmId)
{
case IDC_BTN_1:
{
DialogWindow_OnBtn1();
MessageBoxA(NULL, "Some message", "Some title", MB_OK);
return (INT_PTR)TRUE;
} break;
case IDC_BTN_2:
{
DialogWindow_OnBtn2();
return (INT_PTR)TRUE;
} break;
// ...
case IDCANCEL:
{
// Close window
DefWindowProc(hWnd, WM_CLOSE, wParam, lParam);
} break;
case IDOK:
{
// Close window
DefWindowProc(hWnd, WM_CLOSE, wParam, lParam);
} break;
}
}
}
case WM_CLOSE:
DefWindowProc(hWnd, message, wParam, lParam);
return (INT_PTR)TRUE;
break;
case WM_DESTROY:
PostQuitMessage(0);
return (INT_PTR)TRUE;
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return (INT_PTR)FALSE;
}
第二个窗口(图形)创建:
HRESULT GraphicWindow_OnCreate(HINSTANCE hInst)
{
HWND g_hGraphicWindow = NULL;
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = GraphicWindow_WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICO));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
wcex.lpszClassName = _T("MyApp");
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
if(!RegisterClassEx(&wcex))
{
DWORD dwError = GetLastError();
if(dwError != ERROR_CLASS_ALREADY_EXISTS)
{
MessageBoxA(NULL, "GraphicWindow: RegisterClass() failed!", "Error", MB_OK | MB_ICONERROR);
return HRESULT_FROM_WIN32(dwError);
}
}
// Set window's initial size, but it might be changed later
int nDefaultWidth = 320;
int nDefaultHeight = 240;
RECT rc;
SetRect(&rc, 0, 0, nDefaultWidth, nDefaultHeight);
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
// Create the window
g_hGraphicWindow = CreateWindowA("MyApp", "GraphicWindow", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, (rc.right - rc.left), (rc.bottom - rc.top), 0,
0, hInst, 0);
if(!g_hGraphicWindow)
{
DWORD dwError = GetLastError();
MessageBoxA(NULL, "GraphicWindow: CreateWindow() failed!", "Error", MB_OK | MB_ICONERROR);
return HRESULT_FROM_WIN32(dwError);
}
UpdateWindow(g_hGraphicWindow);
return S_OK;
}
图形窗口过程:
LRESULT CALLBACK GraphicWindow_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_RETURN:
// Some actions ...
break;
case VK_ESCAPE:
// Some actions ...
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_CLOSE:
ShowWindow(hWnd, SW_HIDE);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
我的问题在哪里?请帮帮我。
答案 0 :(得分:2)
我有以下评论:
A
后缀。您需要使用L
为字符串文字添加前缀以指定宽字符串。例如,L"foo"
。hWndParent
时,您可能会将主窗口句柄传递为CreateDialog
。否则,无模式dailog将无主,因此有自己的任务栏按钮,并且不会始终显示在主窗口的顶部。hWnd
时,您应该将主窗口句柄作为MessageBox
传递。在消息循环中查看更多详细信息,您不会遵循文档中列出的CreateDialog
规则,其中指出:
要支持键盘导航和其他对话框功能,对话框的消息循环必须调用IsDialogMessage函数。
所以你的消息循环应该是:
while(GetMessage(&msg, NULL, 0, 0))
{
if(!IsDialogMessage(g_hDialogWindow, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
另请注意,我切换到基于GetMessage
的循环。我认为您不需要为您的需求运行热循环。使用GetMessage
允许应用程序的主线程产生CPU并在其空闲时阻塞。
答案 1 :(得分:0)
在对话程序中,请勿使用DefWindowProc
。