NO

Author Topic: Thread termination  (Read 4083 times)

oat444

  • Guest
Thread termination
« on: February 07, 2008, 10:18:33 AM »
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: [Select]
#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);

Source Code File
Code: [Select]
#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;
    }
}

Please reply.

Offline Christian

  • Administrator
  • Member
  • *****
  • Posts: 142
    • http://www.pellesc.de
Re: Thread termination
« Reply #1 on: February 07, 2008, 10:27:32 AM »
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: [Select]
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.

Christian
www.pellesc.de - German PellesC mirror (now available in german and english)

oat444

  • Guest
Re: Thread termination
« Reply #2 on: February 07, 2008, 12:26:48 PM »
Hello,

I tried following your advice, but the thread still won't terminate.

Offline Christian

  • Administrator
  • Member
  • *****
  • Posts: 142
    • http://www.pellesc.de
Re: Thread termination
« Reply #3 on: February 07, 2008, 01:12:18 PM »
Please take a look here:

Code: [Select]
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;
www.pellesc.de - German PellesC mirror (now available in german and english)

oat444

  • Guest
Re: Thread termination
« Reply #4 on: February 13, 2008, 05:00:01 PM »
Thank you very much for your help.

I also found another way:

Code: [Select]
static void Main_OnDestroy(HWND hwnd){
   PostQuitMessage(0);
   ExitThread(0);
}