2004-10-21 04:59:01 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2005-11-12 08:40:47 +00:00
|
|
|
ULONG DbgPrint(PCH Format,...);
|
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
typedef struct _THRDCREATEWIN
|
|
|
|
{
|
|
|
|
HANDLE hThread;
|
|
|
|
DWORD ThreadId;
|
|
|
|
LPSTR Caption;
|
|
|
|
HWND *Parent;
|
|
|
|
HWND Window;
|
|
|
|
DWORD Style;
|
|
|
|
POINT Position;
|
|
|
|
SIZE Size;
|
|
|
|
} THRDCREATEWIN, *PTHRDCREATEWIN;
|
|
|
|
|
|
|
|
static HINSTANCE hAppInstance;
|
|
|
|
static HANDLE WinCreatedEvent;
|
|
|
|
static THRDCREATEWIN wnds[3];
|
|
|
|
|
|
|
|
LRESULT WINAPI MultiWndProc(HWND, UINT, WPARAM, LPARAM);
|
|
|
|
|
|
|
|
DWORD WINAPI
|
|
|
|
WindowThreadProc(LPVOID lpParameter)
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
char caption[64];
|
|
|
|
PTHRDCREATEWIN cw = (PTHRDCREATEWIN)lpParameter;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
sprintf(caption, cw->Caption, GetCurrentThreadId());
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
cw->Window = CreateWindow("MultiClass",
|
|
|
|
caption,
|
|
|
|
cw->Style | WS_VISIBLE,
|
|
|
|
cw->Position.x,
|
|
|
|
cw->Position.y,
|
|
|
|
cw->Size.cx,
|
|
|
|
cw->Size.cy,
|
|
|
|
(cw->Parent ? *(cw->Parent) : 0),
|
|
|
|
NULL,
|
|
|
|
hAppInstance,
|
|
|
|
NULL);
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
SetEvent(WinCreatedEvent);
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
if(!cw->Window)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "CreateWindow failed (last error 0x%lX)\n",
|
|
|
|
GetLastError());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
CreateWindow("BUTTON","Sleep",WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP|BS_PUSHBUTTON, 10, 10, 70, 23, cw->Window, (PVOID)1, hAppInstance, NULL);
|
|
|
|
CreateWindow("BUTTON","1",WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP|BS_PUSHBUTTON, 83, 10, 20, 23, cw->Window, (PVOID)2, hAppInstance, NULL);
|
|
|
|
CreateWindow("BUTTON","2",WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP|BS_PUSHBUTTON, 105, 10, 20, 23, cw->Window, (PVOID)3, hAppInstance, NULL);
|
|
|
|
CreateWindow("BUTTON","3",WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP|BS_PUSHBUTTON, 127, 10, 20, 23, cw->Window, (PVOID)4, hAppInstance, NULL);
|
|
|
|
while(GetMessage(&msg, NULL, 0, 0))
|
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-05-07 21:24:31 +00:00
|
|
|
int WINAPI
|
2004-10-21 04:59:01 +00:00
|
|
|
WinMain(HINSTANCE hInstance,
|
|
|
|
HINSTANCE hPrevInstance,
|
|
|
|
LPSTR lpszCmdLine,
|
|
|
|
int nCmdShow)
|
|
|
|
{
|
|
|
|
WNDCLASS wc;
|
|
|
|
int i;
|
|
|
|
HANDLE Threads[3];
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
hAppInstance = hInstance;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
WinCreatedEvent = CreateEvent(NULL,
|
|
|
|
FALSE,
|
|
|
|
FALSE,
|
|
|
|
NULL);
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
if(!WinCreatedEvent)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Failed to create event (last error 0x%lX)\n",
|
|
|
|
GetLastError());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
wc.lpszClassName = "MultiClass";
|
|
|
|
wc.lpfnWndProc = MultiWndProc;
|
|
|
|
wc.style = CS_VREDRAW | CS_HREDRAW;
|
|
|
|
wc.hInstance = hInstance;
|
|
|
|
wc.hIcon = LoadIcon(NULL, (LPCTSTR) IDI_APPLICATION);
|
|
|
|
wc.hCursor = LoadCursor(NULL, (LPCTSTR) IDC_ARROW);
|
|
|
|
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
|
|
|
|
wc.lpszMenuName = NULL;
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 0;
|
|
|
|
if (RegisterClass(&wc) == 0)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "RegisterClass failed (last error 0x%lX)\n",
|
|
|
|
GetLastError());
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
wnds[0].Caption = "TopLevel1 (ThreadID: %d)";
|
|
|
|
wnds[0].Parent = NULL;
|
|
|
|
wnds[0].Style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
|
|
wnds[0].Position.x = wnds[0].Position.y = 0;
|
|
|
|
wnds[0].Size.cx = 320;
|
|
|
|
wnds[0].Size.cy = 240;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
wnds[1].Caption = "Child1 of TopLevel1 (ThreadID: %d)";
|
|
|
|
wnds[1].Parent = &wnds[0].Window;
|
|
|
|
wnds[1].Style = WS_CHILD | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
|
|
wnds[1].Position.x = 20;
|
|
|
|
wnds[1].Position.y = 120;
|
|
|
|
wnds[1].Size.cx = wnds[1].Size.cy = 240;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
wnds[2].Caption = "TopLevel2 (ThreadID: %d)";
|
|
|
|
wnds[2].Parent = NULL;
|
|
|
|
wnds[2].Style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
|
|
|
wnds[2].Position.x = 400;
|
|
|
|
wnds[2].Position.y = 0;
|
|
|
|
wnds[2].Size.cx = 160;
|
|
|
|
wnds[2].Size.cy = 490;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
for(i = 0; i < (sizeof(wnds) / sizeof(THRDCREATEWIN)); i++)
|
|
|
|
{
|
|
|
|
wnds[i].hThread = CreateThread(NULL,
|
|
|
|
0,
|
|
|
|
WindowThreadProc,
|
|
|
|
&wnds[i],
|
|
|
|
0,
|
|
|
|
&wnds[i].ThreadId);
|
|
|
|
Threads[i] = wnds[i].hThread;
|
|
|
|
if(!wnds[i].hThread)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "CreateThread #%i failed (last error 0x%lX)\n",
|
|
|
|
i, GetLastError());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
WaitForSingleObject(WinCreatedEvent, INFINITE);
|
|
|
|
}
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
WaitForMultipleObjects(sizeof(Threads) / sizeof(HANDLE), &Threads[0], TRUE, INFINITE);
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
UnregisterClass("MultiClass", hInstance);
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK MultiWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
PAINTSTRUCT ps;
|
|
|
|
HDC hDC;
|
|
|
|
RECT Client;
|
|
|
|
HBRUSH Brush;
|
|
|
|
DWORD Ret;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
static COLORREF Colors[] =
|
|
|
|
{
|
|
|
|
RGB(0x00, 0x00, 0x00),
|
|
|
|
RGB(0x80, 0x00, 0x00),
|
|
|
|
RGB(0x00, 0x80, 0x00),
|
|
|
|
RGB(0x00, 0x00, 0x80),
|
|
|
|
RGB(0x80, 0x80, 0x00),
|
|
|
|
RGB(0x80, 0x00, 0x80),
|
|
|
|
RGB(0x00, 0x80, 0x80),
|
|
|
|
RGB(0x80, 0x80, 0x80),
|
|
|
|
RGB(0xff, 0x00, 0x00),
|
|
|
|
RGB(0x00, 0xff, 0x00),
|
|
|
|
RGB(0x00, 0x00, 0xff),
|
|
|
|
RGB(0xff, 0xff, 0x00),
|
|
|
|
RGB(0xff, 0x00, 0xff),
|
|
|
|
RGB(0x00, 0xff, 0xff),
|
|
|
|
RGB(0xff, 0xff, 0xff)
|
|
|
|
};
|
|
|
|
static unsigned CurrentColor = 0;
|
|
|
|
|
|
|
|
switch(msg)
|
|
|
|
{
|
|
|
|
case WM_PAINT:
|
|
|
|
hDC = BeginPaint(hWnd, &ps);
|
|
|
|
GetClientRect(hWnd, &Client);
|
|
|
|
Brush = CreateSolidBrush(Colors[CurrentColor]);
|
|
|
|
FillRect(hDC, &Client, Brush);
|
|
|
|
DeleteObject(Brush);
|
|
|
|
CurrentColor++;
|
|
|
|
if (sizeof(Colors) / sizeof(Colors[0]) <= CurrentColor)
|
|
|
|
{
|
|
|
|
CurrentColor = 0;
|
|
|
|
}
|
|
|
|
EndPaint(hWnd, &ps);
|
|
|
|
break;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
case WM_COMMAND:
|
|
|
|
switch(LOWORD(wParam))
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
Sleep(20000);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
if(SendMessageTimeout(wnds[LOWORD(wParam) - 2].Window, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 1000, &Ret))
|
|
|
|
{
|
|
|
|
DbgPrint("SendMessageTimeout() OK");
|
|
|
|
MessageBox(hWnd, "SendMessageTimeout() OK", NULL, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(GetLastError() == ERROR_TIMEOUT)
|
|
|
|
{
|
|
|
|
DbgPrint("SendMessageTimeout() Timeout");
|
|
|
|
MessageBox(hWnd, "SendMessageTimeout() Timeout", NULL, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DbgPrint("SendMessageTimeout() Failed");
|
|
|
|
MessageBox(hWnd, "SendMessageTimeout() Failed", NULL, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2005-05-07 21:24:31 +00:00
|
|
|
|
2004-10-21 04:59:01 +00:00
|
|
|
case WM_DESTROY:
|
|
|
|
PostQuitMessage(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|