Page 7 of 7

Re: What do you hate on the current OS that runs on your pc?

Posted: Sat Aug 25, 2012 2:11 am
by Combuster
Suddenly what should be one call to SetWidgetText() turns into a maze of trying to pass a message and a pointer and a length into the "correct" thread
What maze?

Re: What do you hate on the current OS that runs on your pc?

Posted: Sat Aug 25, 2012 2:25 am
by bluemoon
Wrong again. Try the following code with Windows SDK 7.1+ and run on Windows7. In short, you're totally fine calling GUI function from any thread.
As a side note, it's also fine to call GDI function, which I (and many people) did for background GDI text rendering onto textures in game project (however it's a bit complex to demonstrate here).

PS. Can someone please detach this to a new thread?

Code: Select all

#include <Windows.h>
#include <stdio.h>


const TCHAR szAppName[] = L"Test";
CRITICAL_SECTION    ListBoxLocker;
HWND                hListBox = NULL;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp);

// Test Thread to work with list box: it generate some item and append to list box
DWORD WINAPI TestThread(LPVOID lpParameter) {
    TCHAR text[256];
    int i, num = (int)lpParameter; // ugly casting pointer to int, but hey it's just a test
    for ( i=0; i<50; i++ ) {
        _snwprintf (text, 256, L"Test Thread #%d", i+num );
        // EnterCriticalSection(&ListBoxLocker); // It seems windows do protection and we are good without lock here
        SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)text);
        // LeaveCriticalSection(&ListBoxLocker);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
	MSG msg;
	WNDCLASSEX wc;
	HWND	hwnd;

    // Initialize Our locker
    InitializeCriticalSectionAndSpinCount ( &ListBoxLocker, 100 );

    // Standard window creation code
	wc.cbClsExtra	= 0;
	wc.cbSize		= sizeof(wc);
	wc.cbWndExtra	= 0;
	wc.hbrBackground= (HBRUSH)COLOR_WINDOW;
	wc.hCursor		= LoadCursor(NULL,IDC_ARROW);
	wc.hIcon		= NULL;
	wc.hIconSm		= NULL;
	wc.hInstance	= hInstance;
	wc.lpfnWndProc	= WindowProc;
	wc.lpszClassName= szAppName;
	wc.lpszMenuName	= NULL;
	wc.style		= CS_VREDRAW|CS_HREDRAW;
	RegisterClassEx(&wc);

    hwnd = CreateWindowEx( 0, szAppName, szAppName,
				WS_OVERLAPPEDWINDOW,
				CW_USEDEFAULT, CW_USEDEFAULT, 640, 640,
				NULL, NULL,
				hInstance, NULL);

	ShowWindow(hwnd,SW_SHOW);
	UpdateWindow(hwnd);

    // Standard message loop
	while ( GetMessage(&msg, 0, 0, 0) ) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
		if ( msg.message == WM_QUIT ) break;
	}
	return msg.wParam;
}


LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
	switch(msg) {
	case WM_CREATE:
		{
            CREATESTRUCT* lpcs = (CREATESTRUCT*)lp;
            // Create our child list box here
            hListBox = CreateWindowEx(WS_EX_CLIENTEDGE, L"Listbox", NULL,
                    WS_CHILD | WS_VISIBLE | WS_VSCROLL,
                    10, 10, lpcs->cx-20,
                    lpcs->cy-20, hwnd, (HMENU)1,
                    lpcs->hInstance, NULL);
            // Let's start some thread to work with list box
            CreateThread ( NULL, 0, TestThread, (void*)1, 0, NULL );
            CreateThread ( NULL, 0, TestThread, (void*)100, 0, NULL );
            CreateThread ( NULL, 0, TestThread, (void*)200, 0, NULL );
		} break;
	case WM_DESTROY:
		PostQuitMessage(0); 
		break;
	}
	return DefWindowProc(hwnd,msg,wp,lp);
}