C language > Windows questions
Thread termination
(1/1)
oat444:
Hello, I'm new to Win32 programming.
I am learning Win32 programming by trying it out practically.
I made an example before which works correctly, but this one doesn't, since, whenever I close it with the 'X' button on the system menu, the window is destroyed, but the application thread continues to run, consuming a lot of system resources.
Whenever I close it with the button, it terminates correctly if I use 'PostQuitMessage(0)', but it has the same effect that is stated above when I use 'DestroyWindow(hwnd)'.
Here is the code:
Header File
--- Code: ---#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <tchar.h>
#define NELEMS(a) (sizeof(a) / sizeof((a)[0]))
static HINSTANCE ghInstance;
static void __declspec(noreturn) Calc_OnDestroy(HWND);
static void Calc_OnPaint(HWND);
static void Calc_OnCommand(HWND, int, HWND, UINT);
static LRESULT WINAPI CalcWndProc(HWND, UINT, WPARAM, LPARAM);
--- End code ---
Source Code File
--- Code: ---#include "main.h"
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
INITCOMMONCONTROLSEX icc;
WNDCLASS wc;
MSG msg;
HWND hwnd;
HWND btn;
ghInstance = hInstance;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&icc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = NULL;
wc.hInstance = ghInstance;
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpfnWndProc = CalcWndProc;
wc.lpszClassName = _T("CalcWnd");
wc.lpszMenuName = NULL;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&wc))
return 1;
hwnd = CreateWindow(_T("CalcWnd"), _T("Simple Calculator"), WS_SYSMENU | WS_MINIMIZEBOX | WS_OVERLAPPED, 10, 10, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, ghInstance, NULL);
btn = CreateWindow(_T("BUTTON"), _T("Click Me"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 10, 10, 200, 50, hwnd, NULL, NULL, NULL);
if (!hwnd || !btn)
return 1;
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
while (GetMessage(&msg, hwnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
static LRESULT CALLBACK CalcWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
HANDLE_MSG(hwnd, WM_DESTROY, Calc_OnDestroy);
HANDLE_MSG(hwnd, WM_PAINT, Calc_OnPaint);
HANDLE_MSG(hwnd, WM_COMMAND, Calc_OnCommand);
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
static void Calc_OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
static void Calc_OnPaint(HWND hwnd)
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &ps.rcPaint);
EndPaint(hwnd, &ps);
}
static void Calc_OnCommand(HWND hwnd, int id, HWND ctrl, UINT code)
{
switch (id) {
case BN_CLICKED:
DestroyWindow(hwnd);//PostQuitMessage(0) terminates correctly, but is slow.
break;
}
}
--- End code ---
Please reply.
Christian:
Hello,
you can't use 'DestroyWindow()' to close the application, it only sends a WM_DESTROY message. If your application doesn't quit your thread, who else?
Here you can read the description of 'PostQuitMessage' from the Microsoft-PSDK:
--- Code: ---The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit).
It is typically used in response to a WM_DESTROY message.
--- End code ---
Christian
oat444:
Hello,
I tried following your advice, but the thread still won't terminate.
Christian:
Please take a look here:
--- Code: ---case WM_CLOSE:
// Create the message box. If the user clicks
// the Yes button, destroy the main window.
if (MessageBox(hwnd, szConfirm, szAppName, MB_YESNOCANCEL) == IDYES)
DestroyWindow(hwndMain);
else
return 0;
case WM_DESTROY:
// Post the WM_QUIT message to
// quit the application terminate.
PostQuitMessage(0);
return 0;
--- End code ---
oat444:
Thank you very much for your help.
I also found another way:
--- Code: ---static void Main_OnDestroy(HWND hwnd){
PostQuitMessage(0);
ExitThread(0);
}
--- End code ---
Navigation
[0] Message Index
Go to full version