GUI freezes after few seconds in this little Dialog based apllication

Pages: 12
Don't create a thread, use a timer.

In WM_INTIDIALOG, call SetTimer() to start a timer. This will send WM_TIMER messages to the window.

Handle WM_TIMER, and increment a static counter. Use the counter to create a string that looks like: "Hello%d". Use SetWindowText to display the string.
I already said i can't afford to slow it down. So i can' t use a timer.
Can anyone show the CreateThread() way to me that i never had to use threads please?
Thanks
Last edited on
I don't know why you won't listen to people who know better than you, but anyway...

You'll also need to include <process.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void sayHello(void *H)
{
  HWND hWnd = (HWND)H;
  while(IsWindow(hWnd))
  {
    SetWindowText(hWnd,"Hello1");
    Sleep(100);
    SetWindowText(hWnd,"Hello2");
    Sleep(100);
    SetWindowText(hWnd,"Hello3");
    Sleep(100);
    SetWindowText(hWnd,"Hello4");
    Sleep(100);
    SetWindowText(hWnd,"Hello5");
    Sleep(100);
  }
  _endthread();
}

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
            return TRUE;

        case WM_CLOSE:
            EndDialog(hwndDlg, 0);
            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDC_BTN_QUIT:
                    EndDialog(hwndDlg, 0);
                    return TRUE;

                case IDC_BTN_TEST:
                    HWND handle = GetDlgItem(hwndDlg, 1003);
                    _beginthread(sayHello,0,(void*)handle);
                    // CreateThread(0,0,sayHello,(void*)handle,0,0);
                    return TRUE;
            }
    }

    return FALSE;
}
Last edited on
Maybe you are Superman and your super eyes can "see" more than few changes of window title per second. We, the humans, can't see them anyway.

Btw, I think you will also reject Texan40 example as this also "slows down" the application by using Sleep(). :)
I already said i can't afford to slow it down. So i can' t use a timer.
A timer doesn't slow you down.

You have to realise that every thing that happens on the GUI sends a message. It's not like a console where the only thing going to stdout is your text. Although you just see your text, there's a whole raft of messages that are sent around the app to get this displayed.

If you start generating screen updates from a different thread, you really should to use PostThreadMessage to get the message back to the GUI thread. Using a seperate thread doesn't increase the display speed.

For this task, a timer is what you should be using.
EDIT2: I only just registered the comments about not using a timer and performance.
What are you actually trying to do?? After all, the screen refresh rate is what's
going to finally limit what you can display.


EDIT: the code below does work with DialogBox, rather than CreateDialog, if you (a) remove
the message loop, (b) remove the WM_DESTROY handler, and (c) replace the calls to
DestroyWindow() with EndDialog(), as originally there. But I've generally ecountered the
CreateDialog version for dialog-based apps.

For a dialog which is the main window, you should be using more normally use CreateDialog (to create a modeless dialog) rather than DialogBox. Then the message loop can be more or less like any other normal window. There is no need to spawn an extra thread!

main.cpp, modified to use CreateWindow and a normal message loop. It has also been altered to use a timer as suggested by mordoran, kbw, etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "resource.h"

HINSTANCE hInst    = NULL;
UINT_PTR  timerId  = 0;
int       helloIdx = 0;

const UINT_PTR timerStartId    = 1000;
const UINT     timerElapseTime = 100; // milliseconds

// TODO Rework this to be more elegant!
void sayHello(HWND hwndDlg)
{
    HWND handle = GetDlgItem(hwndDlg, ID_CONTROLSTATIC);

    switch(helloIdx % 5)
    {
        case 0: SetWindowText(handle, "Hello1"); break;
        case 1: SetWindowText(handle, "Hello2"); break;
        case 2: SetWindowText(handle, "Hello3"); break;
        case 3: SetWindowText(handle, "Hello4"); break;
        case 4: SetWindowText(handle, "Hello5"); break;
        default: SetWindowText(handle, "??????"); // should never reach here
    }

    ++helloIdx;
}

INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
            return TRUE;

        case WM_DESTROY:
            PostQuitMessage(0);
            return TRUE;

        case WM_CLOSE:
            if(0 != timerId)
            {
                KillTimer(hwndDlg, timerId);
                timerId = 0;
            }
            DestroyWindow(hwndDlg);
            return TRUE;

        case WM_TIMER:
            sayHello(hwndDlg);
            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDC_BTN_QUIT:
                    DestroyWindow(hwndDlg);
                    return TRUE;
                case IDC_BTN_TEST:
                    if(0 == timerId)
                    {
                        timerId = SetTimer(hwndDlg, timerStartId, timerElapseTime, NULL);
                    }
                    else
                    {
                        KillTimer(hwndDlg, timerId);
                        timerId = 0;
                    }
                    return TRUE;
            }
    }

    return FALSE;
}

// This is the latest approved signature, see:
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633559%28v=vs.85%29.aspx
int CALLBACK WinMain( HINSTANCE  hInstance,
                      HINSTANCE  hPrevInstance,
                      LPSTR      lpCmdLine,
                      int        nCmdShow )
{
    hInst = hInstance;

    HWND hWnd = CreateDialog( hInstance,
                              MAKEINTRESOURCE(DLG_MAIN),
                              NULL,
                              DialogProc );

    MSG msg = {0};
    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(!IsDialogMessage(hWnd, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return msg.wParam;
}


resource.h, as orignally

1
2
3
4
5
6
#include <windows.h>

#define DLG_MAIN 101
#define IDC_BTN_TEST 1001
#define IDC_BTN_QUIT 1002
#define ID_CONTROLSTATIC 1003 


resource.rc, tweaked so all controls use the specific control type rather than CONTOL. I also added the visible flag so that you don't need an explicit call to ShowWindow after creating the dialog.

1
2
3
4
5
6
7
8
9
10
#include "resource.h"

DLG_MAIN DIALOGEX 6, 5, 194, 106
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Test Application"
BEGIN
  PUSHBUTTON "&Test", IDC_BTN_TEST, 138,  5, 46, 15
  LTEXT, "TEXT HERE", ID_CONTROLSTATIC, 35, 35, 50, 8
  PUSHBUTTON "&Quit", IDC_BTN_QUIT, 138, 29, 46, 15
END


PS A recent-ish tutorial on the subject:

http://www.codeproject.com/Articles/227831/A-dialog-based-Win32-C-program
A dialog based Win32 C program, step by step
By Rodrigo Cesar de Freitas Dias
9 Aug 2011
Last edited on
I'm sorry we have a little misunderstanding here.
What i was looking for when i first started this thread, was a way to overcome the freezing issue that arises after a few text updates. Simple.
I created the sayHello() function just as a stand-in, because i wanted it to simulate text updates.
With this said, i must point out clearly (maybe should have done this before but i thought my problem was clear) that the real application i'm coding doesn't have to print out regurarly. Instead, it will be printing out very irregularly. This is, i think, the misunderstanding behind my stand-in function sayHello() we are facing here.
What i meant with "i can't afford to slow it down" was not just what it means (application will have to be faster as possible) but also that i cannot solve this issue just by setting up a timer that stops the execution for a predetermined little while so that the GUI doesn't freeze up (which by the way it's ridiculus imho: i believe it should be able to not freeze just because there are too many text updates, maybe hang on the single text updates like for a little breathe but not freeze the whole thing) because in the real application text updates are not sent regularly.
The sayHello() function serves only to tell that the text is being updated.
I hope you get my point now.
I firstly have to thank Texan40 because he answered very clearly what i needed. I learned how to start a thread and use it in 5 minutes after i read his code. Thank you Texan40!
kbw, to call PostThreadMessage when using a different thread sounds fine to me (even though i faced no problems yet with the new thread), but i have no idea where to call it and what parameters exactly. You have to cooperate writing the exact code that works with the stand-in function here if you really want to help me.
And finally andywestken: thank you for replying with written code. I learned about timers even if i don't think i'm going to use them now. About using CreateDialog instead od DialogBox i don't know.. right now i can't tell i faced any problems yet with that. I understand it may sound weird to code a whole program around DialogBox but hey.. this is what i'm doing now and it seams to work.
Thank you all, i'm marking this as solved.
Last edited on
Topic archived. No new replies allowed.
Pages: 12