#c #user-interface #winapi
Вопрос:
- Когда я пытаюсь закрыть диалоговое окно, я ожидаю, что приложение закроется, но этого не происходит. Я предполагаю, что что-то не так
WM_CLOSE
. - Приложение не может быть изменено по размеру. Как мне это сделать?
- Действительно ли мне это нужно
UpdateWindow(hWnd)
?
#include <Windows.h>
#include "resource.h"
#pragma comment(linker, ""/manifestdependency:type='win32'
name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"")
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
INT_PTR CALLBACK DialogProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch (Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, IDOK);
break;
case IDCANCEL:
EndDialog(hwnd, IDCANCEL);
break;
}
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
HWND hWnd = CreateDialogParamW(hInstance, MAKEINTRESOURCEW(IDD_MAIN), nullptr, amp;DialogProc, 0);
if (!hWnd)
{
MessageBoxW(nullptr, L"Dialog Creation Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);
MSG msg;
while (GetMessageW(amp;msg, hWnd, 0, 0))
{
TranslateMessage(amp;msg);
DispatchMessageW(amp;msg);
}
return msg.wParam;
}
Ресурс.rc
// Microsoft Visual C generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h"""
END
3 TEXTINCLUDE
BEGIN
"rn"
""
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 302
TOPMARGIN, 7
BOTTOMMARGIN, 169
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 309, 176
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Test"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LISTBOX IDC_LIST2,48,30,235,56,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
GROUPBOX "Static",IDC_STATIC,146,92,48,40
PUSHBUTTON "Button1",IDC_BUTTON1,215,127,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//
IDD_MAIN AFX_DIALOG_LAYOUT
BEGIN
0
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
ресурс.ч
//{{NO_DEPENDENCIES}}
// Microsoft Visual C generated include file.
// Used by Resource.rc
//
#define IDD_MAIN 103
#define IDC_LIST2 1005
#define IDC_BUTTON1 1006
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 105
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Комментарии:
1.
EndDialog
не влияет на диалог, созданный сCreateDialogParamW
помощью (внутренне он только публикуетсяWM_NULL
).WM_CLOSE
вы должны получить, если нажмете на кнопку закрытия или atl f4. и вы выбираетеDS_MODALFRAME
— он не может быть изменен2. @RbMm, спасибо тебе!
DS_FIXEDSYS
исправлено изменение размера. А как насчет закрытия? Что я должен использовать, чтобы исправить это?3. Похоже, вы не вызываете WndProc по умолчанию для
WM_DESTROY
сообщения. Вашеdefault
дело возвращаетсяFALSE
дляWM_DESTROY
, которое сообщает системе, что вы обработали сообщение.4. @AdrianMole — в
DialogProc
никогда не нужно вызывать WndProc по умолчанию5. @nop — А как насчет закрытия? вместо
EndDialog
этого позвонитеDestroyWindow
, случай WM_CLOSE вы можете удалить вообще.PostQuitMessage(0);
звонок отWM_NCDESTROY
Ответ №1:
Проблема в том, что вы передаете hWnd
в качестве параметра GetMessage()
. Это приводит GetMessage()
к получению сообщений только для окна. Но WM_QUIT
отправляется не в ваше окно, а в вашу нить. Поскольку GetMessage()
сообщение никогда не извлекается WM_QUIT
, цикл сообщений никогда не завершается.
Правильный подход состоит в том, чтобы пройти nullptr
вместо hWnd
этого .
Комментарии:
1. да, но все же один момент здесь —
while (GetMessageW(amp;msg, hWnd, 0, 0))
неверный результат проверки. должно бытьwhile (0 < GetMessageW(amp;msg, hWnd, 0, 0))
, потому, что api возвращает-1
ошибку. если использовать вторую форму — это также прервет цикл — потому что -1 возвращается послеDestroyWindow
вызова иhWnd
больше недействителен2. Видеть Опасности фильтрации оконных сообщений и Когда GetMessage вернет -1?