mirror of
https://github.com/reactos/wine.git
synced 2024-11-30 07:00:30 +00:00
752 lines
18 KiB
C
752 lines
18 KiB
C
/* Windows GUI Behaviour Tester */
|
|
/* by Ove Kåven */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <windows.h>
|
|
|
|
#include "guitest.rh"
|
|
|
|
/* checks to include */
|
|
#define LOGGING /* can be undefined under Wine and use -debugmsg +message instead */
|
|
#define MAIN_STYLE WS_OVERLAPPEDWINDOW|WS_HSCROLL
|
|
#define MAIN_EXSTYLE 0
|
|
#undef TEST_DESTROY_MAIN
|
|
#define SHOW_SUB
|
|
#undef TEST_DIALOG
|
|
#define RESIZE_DIALOG
|
|
#undef TEST_SUBDIALOG
|
|
#undef TEST_COMMCTL
|
|
|
|
/************************/
|
|
/*** GLOBAL VARIABLES ***/
|
|
/************************/
|
|
|
|
HINSTANCE hInst;
|
|
DWORD StartTime;
|
|
HWND hListBox,hMainWnd,hSubWnd;
|
|
HWND hButton[4]={0,0,0,0};
|
|
HWND hDialog=0,hGroup=0,hSubDlg=0;
|
|
WNDPROC wndButton[4],wndDialog,wndGroup,wndSubDlg;
|
|
BOOL Clicked=0,Ready=0;
|
|
int State=0,Rec=0;
|
|
#define STATE_CREATE 0
|
|
#define STATE_DESTROY 1
|
|
#define STATE_SHOW 2
|
|
#define STATE_UPDATE 3
|
|
#define STATE_DIALOG 4
|
|
#define STATE_TEST 5
|
|
#define STATE_DIRECT 6
|
|
#define STATE_DISPATCH 7
|
|
#define STATE_RECURS 8
|
|
char*StateName[]={
|
|
"Creat",
|
|
"Destr",
|
|
"Show ",
|
|
"Updat",
|
|
"Dialg",
|
|
"Test ",
|
|
"Call ",
|
|
"Disp ",
|
|
"RCall"
|
|
};
|
|
|
|
static char wclassname[] = "GUITestClass";
|
|
static char wcclassname[] = "GUITestChildClass";
|
|
static char winname[] = "GUITest";
|
|
|
|
/**************************/
|
|
/*** LOGGING FACILITIES ***/
|
|
/**************************/
|
|
|
|
struct MSGNAMES {
|
|
int msg;
|
|
char*name;
|
|
} MsgNames[]={
|
|
#define MSG(x) {x,#x},
|
|
#define MSG2(x,y) {y,#x},
|
|
#define ENDMSG {0}
|
|
|
|
/* we get these in CreateWindow */
|
|
MSG(WM_GETMINMAXINFO)
|
|
MSG(WM_NCCREATE)
|
|
MSG(WM_NCCALCSIZE)
|
|
MSG(WM_CREATE)
|
|
MSG(WM_PARENTNOTIFY)
|
|
|
|
/* we get these in ShowWindow */
|
|
MSG(WM_SHOWWINDOW)
|
|
MSG(WM_WINDOWPOSCHANGING)
|
|
MSG(WM_QUERYNEWPALETTE)
|
|
MSG(WM_ACTIVATEAPP)
|
|
MSG(WM_NCACTIVATE)
|
|
MSG(WM_GETTEXT)
|
|
MSG(WM_ACTIVATE)
|
|
MSG(WM_SETFOCUS)
|
|
MSG(WM_NCPAINT)
|
|
MSG(WM_ERASEBKGND)
|
|
MSG(WM_WINDOWPOSCHANGED)
|
|
MSG(WM_SIZE)
|
|
MSG(WM_MOVE)
|
|
|
|
/* we get these in DestroyWindow */
|
|
MSG(WM_KILLFOCUS)
|
|
MSG(WM_DESTROY)
|
|
MSG(WM_NCDESTROY)
|
|
|
|
/* we get these directly sent */
|
|
MSG(WM_NCHITTEST)
|
|
MSG(WM_SETCURSOR)
|
|
MSG(WM_MOUSEACTIVATE)
|
|
MSG(WM_CHILDACTIVATE)
|
|
MSG(WM_COMMAND)
|
|
MSG(WM_SYSCOMMAND)
|
|
|
|
/* posted events */
|
|
MSG(WM_MOUSEMOVE)
|
|
MSG(WM_NCMOUSEMOVE)
|
|
MSG(WM_PAINT)
|
|
MSG(WM_LBUTTONDOWN)
|
|
MSG(WM_LBUTTONUP)
|
|
MSG(WM_LBUTTONDBLCLK)
|
|
MSG(WM_NCLBUTTONDOWN)
|
|
MSG(WM_NCLBUTTONUP)
|
|
MSG(WM_NCLBUTTONDBLCLK)
|
|
|
|
MSG(WM_KEYDOWN)
|
|
MSG(WM_KEYUP)
|
|
MSG(WM_CHAR)
|
|
|
|
#ifdef WIN32
|
|
MSG(WM_CTLCOLORBTN)
|
|
MSG(WM_CTLCOLORDLG)
|
|
MSG(WM_CTLCOLORSTATIC)
|
|
#else
|
|
MSG(WM_CTLCOLOR)
|
|
#endif
|
|
|
|
/* moving and sizing */
|
|
MSG2(WM_ENTERSIZEMOVE,0x0231)
|
|
MSG2(WM_EXITSIZEMOVE,0x0232)
|
|
#ifdef WIN32
|
|
MSG(WM_SIZING)
|
|
#endif
|
|
|
|
/* menus/dialog boxes */
|
|
MSG(WM_CANCELMODE)
|
|
MSG(WM_ENABLE)
|
|
MSG(WM_SETFONT)
|
|
MSG(WM_INITDIALOG)
|
|
MSG(WM_GETDLGCODE)
|
|
MSG(WM_ENTERIDLE)
|
|
|
|
/* scroll bars */
|
|
MSG(WM_HSCROLL)
|
|
MSG(WM_VSCROLL)
|
|
|
|
/* getting these from Wine but not from Windows */
|
|
MSG2(WM_SETVISIBLE,0x0009) /* unheard of in BC++ 4.52 */
|
|
#ifdef WIN32
|
|
MSG(WM_CAPTURECHANGED)
|
|
#endif
|
|
|
|
ENDMSG};
|
|
|
|
struct MSGNAMES ButMsgs[]={
|
|
MSG(BM_SETSTATE)
|
|
MSG(BM_SETSTYLE)
|
|
|
|
ENDMSG};
|
|
|
|
char*MsgName(UINT msg,HWND hWnd)
|
|
{
|
|
int i;
|
|
static char buffer[64],wclass[64];
|
|
GetClassName(hWnd,wclass,sizeof(wclass));
|
|
|
|
#define MSGSEARCH(msgs) { \
|
|
for (i=0; msgs[i].name&&msgs[i].msg!=msg; i++); \
|
|
if (msgs[i].name) return msgs[i].name; \
|
|
}
|
|
|
|
if (!stricmp(wclass,"Button")) MSGSEARCH(ButMsgs);
|
|
MSGSEARCH(MsgNames);
|
|
/* WM_USER */
|
|
if (msg>=WM_USER) {
|
|
sprintf(buffer,"WM_USER+%04x{%s}",msg-WM_USER,wclass);
|
|
return buffer;
|
|
}
|
|
/* message not found */
|
|
sprintf(buffer,"%04x{%s}",msg,wclass);
|
|
return buffer;
|
|
}
|
|
|
|
char*WndName(HWND hWnd,int state)
|
|
{
|
|
static char buffer[16];
|
|
if (!hWnd) return "0000";
|
|
if (hWnd==hMainWnd || (state==STATE_CREATE && !hMainWnd)) return "main";
|
|
if (hWnd==hSubWnd || (state==STATE_CREATE && !hSubWnd)) return "chld";
|
|
if (hWnd==hDialog || (state==STATE_DIALOG && !hDialog)) return "tdlg";
|
|
if (hWnd==hGroup) return "tgrp";
|
|
if (hWnd==hButton[0]) return "but1";
|
|
if (hWnd==hButton[1]) return "but2";
|
|
if (hWnd==hButton[2]) return "but3";
|
|
if (hWnd==hButton[3]) return "but4";
|
|
if (hWnd==hSubDlg || (state==STATE_CREATE && !hSubDlg)) return "sdlg";
|
|
if (hDialog) {
|
|
int id=GetDlgCtrlID(hWnd);
|
|
if (id) {
|
|
sprintf(buffer,"dlgitem(%d)",id);
|
|
return buffer;
|
|
}
|
|
}
|
|
sprintf(buffer,"%04x",hWnd);
|
|
return buffer;
|
|
}
|
|
|
|
void Log(const char*fmt)
|
|
{
|
|
#ifdef LOGGING
|
|
if (!Clicked) SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)fmt);
|
|
#endif
|
|
}
|
|
|
|
void Logf(const char*fmt,...)
|
|
{
|
|
va_list par;
|
|
static char buffer[256];
|
|
|
|
va_start(par,fmt);
|
|
vsprintf(buffer,fmt,par);
|
|
va_end(par);
|
|
Log(buffer);
|
|
}
|
|
|
|
void LogChildOrder(HWND hWnd)
|
|
{
|
|
HWND hWndChild = GetWindow(hWnd,GW_CHILD);
|
|
static char buffer[256];
|
|
|
|
strcpy(buffer,"child list:");
|
|
while (hWndChild) {
|
|
strcat(strcat(buffer," "),WndName(hWndChild,State));
|
|
hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
|
|
}
|
|
Log(buffer);
|
|
}
|
|
|
|
void LogMessage(int state,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,char*name)
|
|
{
|
|
static char buffer[256];
|
|
DWORD tick=GetTickCount()-StartTime;
|
|
char*msgname=MsgName(msg,hWnd);
|
|
if (!name) name=WndName(hWnd,state);
|
|
switch (msg) {
|
|
case WM_SETFOCUS:
|
|
case WM_KILLFOCUS:
|
|
case WM_SETCURSOR:
|
|
Logf("%04d[%s(%d):%s]%s(%s,%08x)",tick,StateName[state],Rec,
|
|
name,msgname,WndName((HWND)wParam,State),lParam);
|
|
break;
|
|
#ifdef WIN32
|
|
case WM_ENTERIDLE:
|
|
case WM_CTLCOLORBTN:
|
|
case WM_CTLCOLORDLG:
|
|
Logf("%04d[%s(%d):%s]%s(%08x,%s)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,WndName((HWND)lParam,State));
|
|
break;
|
|
#else
|
|
case WM_ENTERIDLE:
|
|
case WM_CTLCOLOR:
|
|
Logf("%04d[%s(%d):%s]%s(%08x,%04x:%s)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,HIWORD(lParam),WndName((HWND)LOWORD(lParam),State));
|
|
break;
|
|
#endif
|
|
case WM_WINDOWPOSCHANGING:
|
|
case WM_WINDOWPOSCHANGED:
|
|
{
|
|
WINDOWPOS*pos=(WINDOWPOS*)lParam;
|
|
#ifdef WIN32
|
|
Logf("%04d[%s(%d):%s]%s(%08x,%p)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,pos);
|
|
#else
|
|
Logf("%04d[%s(%d):%s]%s(%04x,%p)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,pos);
|
|
#endif
|
|
strcpy(buffer,"FLAGS:");
|
|
if (pos->flags&SWP_DRAWFRAME) strcat(buffer," DRAWFRAME");
|
|
if (pos->flags&SWP_HIDEWINDOW) strcat(buffer," HIDEWINDOW");
|
|
if (pos->flags&SWP_NOACTIVATE) strcat(buffer," NOACTIVATE");
|
|
if (pos->flags&SWP_NOCOPYBITS) strcat(buffer," NOCOPYBITS");
|
|
if (pos->flags&SWP_NOMOVE) strcat(buffer," NOMOVE");
|
|
if (pos->flags&SWP_NOOWNERZORDER) strcat(buffer," NOOWNERZORDER");
|
|
if (pos->flags&SWP_NOSIZE) strcat(buffer," NOSIZE");
|
|
if (pos->flags&SWP_NOREDRAW) strcat(buffer," NOREDRAW");
|
|
if (pos->flags&SWP_NOZORDER) strcat(buffer," NOZORDER");
|
|
if (pos->flags&SWP_SHOWWINDOW) strcat(buffer," SHOWWINDOW");
|
|
Log(buffer);
|
|
}
|
|
break;
|
|
case WM_SYSCOMMAND:
|
|
{
|
|
char*cmd=NULL;
|
|
switch (wParam&0xFFF0) {
|
|
#define CASE(x) case SC_##x: cmd=#x; break;
|
|
CASE(CLOSE)
|
|
CASE(DEFAULT)
|
|
CASE(HOTKEY)
|
|
CASE(HSCROLL)
|
|
CASE(KEYMENU)
|
|
CASE(MAXIMIZE)
|
|
CASE(MINIMIZE)
|
|
CASE(MOUSEMENU)
|
|
CASE(MOVE)
|
|
CASE(NEXTWINDOW)
|
|
CASE(PREVWINDOW)
|
|
CASE(RESTORE)
|
|
CASE(SCREENSAVE)
|
|
CASE(SIZE)
|
|
CASE(TASKLIST)
|
|
CASE(VSCROLL)
|
|
#undef CASE
|
|
}
|
|
if (cmd) {
|
|
Logf("%04d[%s(%d):%s]%s(%s+%x,%08x)",tick,StateName[state],Rec,
|
|
name,msgname,cmd,wParam&0xF,lParam);
|
|
} else goto GENERIC_MSG;
|
|
}
|
|
break;
|
|
case WM_HSCROLL:
|
|
case WM_VSCROLL:
|
|
{
|
|
char*cmd=NULL;
|
|
switch (LOWORD(wParam)) {
|
|
#define CASE(x) case SB_##x: cmd=#x; break;
|
|
#define CASE2(h,v) case SB_##h: if (msg==WM_HSCROLL) cmd=#h; else cmd=#v; break;
|
|
CASE(BOTTOM)
|
|
CASE(ENDSCROLL)
|
|
CASE2(LINELEFT,LINEUP)
|
|
CASE2(LINERIGHT,LINEDOWN)
|
|
CASE2(PAGELEFT,PAGEUP)
|
|
CASE2(PAGERIGHT,PAGEDOWN)
|
|
CASE(THUMBPOSITION)
|
|
CASE(THUMBTRACK)
|
|
CASE(TOP)
|
|
#undef CASE
|
|
}
|
|
if (cmd) {
|
|
#ifdef WIN32
|
|
Logf("%04d[%s(%d):%s]%s(%s,%04x,%s)",tick,StateName[state],Rec,
|
|
name,msgname,cmd,HIWORD(wParam),WndName((HWND)lParam,State));
|
|
#else
|
|
Logf("%04d[%s(%d):%s]%s(%04x,%04x,%s)",tick,StateName[state],Rec,
|
|
name,msgname,cmd,LOWORD(lParam),WndName((HWND)HIWORD(lParam),State));
|
|
#endif
|
|
} else goto GENERIC_MSG;
|
|
}
|
|
break;
|
|
default:
|
|
GENERIC_MSG:
|
|
#ifdef WIN32
|
|
Logf("%04d[%s(%d):%s]%s(%08x,%08x)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,lParam);
|
|
#else
|
|
Logf("%04d[%s(%d):%s]%s(%04x,%08x)",tick,StateName[state],Rec,
|
|
name,msgname,wParam,lParam);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/***************************/
|
|
/*** GRAPHICS FACILITIES ***/
|
|
/***************************/
|
|
|
|
void Paint(HWND hWnd)
|
|
{
|
|
HDC dc;
|
|
PAINTSTRUCT ps;
|
|
dc=BeginPaint(hWnd,&ps);
|
|
EndPaint(hWnd,&ps);
|
|
}
|
|
|
|
void FillPattern(HWND hWnd,HDC pdc)
|
|
{
|
|
HDC dc=pdc?pdc:GetDC(hWnd);
|
|
HBRUSH oldbrush;
|
|
RECT rect;
|
|
if (!dc) {
|
|
Logf("failed to acquire DC for window %s",WndName(hWnd,State));
|
|
return;
|
|
} else {
|
|
Logf("acquired DC for %s window %s, painting",
|
|
IsWindowVisible(hWnd)?"visible":"invisible",WndName(hWnd,State));
|
|
}
|
|
GetClientRect(hWnd,&rect);
|
|
oldbrush=SelectObject(dc,GetStockObject(LTGRAY_BRUSH));
|
|
PatBlt(dc,0,0,rect.right,rect.bottom,PATCOPY);
|
|
SelectObject(dc,oldbrush);
|
|
if (!pdc) ReleaseDC(hWnd,dc);
|
|
}
|
|
|
|
void PaintPattern(HWND hWnd)
|
|
{
|
|
HDC dc;
|
|
PAINTSTRUCT ps;
|
|
dc=BeginPaint(hWnd,&ps);
|
|
FillPattern(hWnd,dc);
|
|
EndPaint(hWnd,&ps);
|
|
}
|
|
|
|
/*************************/
|
|
/*** WINDOW PROCEDURES ***/
|
|
/*************************/
|
|
|
|
/* MAIN WINDOW */
|
|
LRESULT FAR CALLBACK _export MainWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult=0;
|
|
RECT rect;
|
|
int OldState=State;
|
|
|
|
State=STATE_RECURS; Rec++;
|
|
if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
|
|
switch (msg) {
|
|
case WM_NCHITTEST:
|
|
lResult=DefWindowProc(hWnd,msg,wParam,lParam);
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
case WM_CHAR:
|
|
if (!Clicked) {
|
|
SetParent(hListBox,hWnd);
|
|
GetClientRect(hWnd,&rect);
|
|
MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
|
|
ShowWindow(hListBox,SW_SHOW);
|
|
SetFocus(hListBox);
|
|
Clicked=TRUE;
|
|
}
|
|
break;
|
|
case WM_SIZE:
|
|
GetClientRect(hWnd,&rect);
|
|
if (Clicked) {
|
|
MoveWindow(hListBox,0,0,rect.right,rect.bottom,TRUE);
|
|
}
|
|
MoveWindow(hSubWnd,0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),TRUE);
|
|
break;
|
|
case WM_PAINT:
|
|
Paint(hWnd);
|
|
break;
|
|
case WM_DESTROY:
|
|
PostQuitMessage(0);
|
|
break;
|
|
default:
|
|
lResult=DefWindowProc(hWnd,msg,wParam,lParam);
|
|
}
|
|
State=OldState; Rec--;
|
|
return lResult;
|
|
}
|
|
|
|
/* CHILD WINDOW */
|
|
LRESULT FAR CALLBACK _export SubWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult=0;
|
|
RECT rect;
|
|
int OldState=State;
|
|
|
|
State=STATE_RECURS; Rec++;
|
|
if (!Clicked) LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
|
|
switch (msg) {
|
|
case WM_PAINT:
|
|
Paint(hWnd);
|
|
break;
|
|
default:
|
|
lResult=DefWindowProc(hWnd,msg,wParam,lParam);
|
|
}
|
|
State=OldState; Rec--;
|
|
return lResult;
|
|
}
|
|
|
|
BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
/* SUBCLASSED CONTROLS */
|
|
LRESULT FAR CALLBACK _export SubClassWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LRESULT lResult=0;
|
|
RECT rect;
|
|
int OldState=State;
|
|
int But=-1;
|
|
|
|
if (hWnd==hButton[0]) But=0; else
|
|
if (hWnd==hButton[1]) But=1; else
|
|
if (hWnd==hButton[2]) But=2; else
|
|
if (hWnd==hButton[3]) But=3;
|
|
|
|
State=STATE_RECURS; Rec++;
|
|
if (!Clicked) {
|
|
LogMessage(OldState,hWnd,msg,wParam,lParam,NULL);
|
|
if (But!=-1) {
|
|
lResult=CallWindowProc((FARPROC)wndButton[But],hWnd,msg,wParam,lParam);
|
|
if (msg==WM_LBUTTONUP) {
|
|
LogChildOrder(GetParent(hWnd));
|
|
}
|
|
}
|
|
else if (hWnd==hDialog) {
|
|
lResult=CallWindowProc((FARPROC)wndDialog,hWnd,msg,wParam,lParam);
|
|
}
|
|
else if (hWnd==hSubDlg) {
|
|
lResult=CallWindowProc((FARPROC)wndSubDlg,hWnd,msg,wParam,lParam);
|
|
}
|
|
else if (hWnd==hGroup) {
|
|
lResult=CallWindowProc((FARPROC)wndGroup,hWnd,msg,wParam,lParam);
|
|
if (msg==WM_SETFOCUS) {
|
|
/* create subdialog */
|
|
if (hSubDlg) {
|
|
#if 0
|
|
SetRect(&rect,0,0,1,1);
|
|
InvalidateRect(hWnd,&rect,FALSE);
|
|
#endif
|
|
} else {
|
|
#ifdef TEST_SUBDIALOG
|
|
State=STATE_CREATE;
|
|
hSubDlg=CreateDialog(hInst,MAKEINTRESOURCE(2),hWnd,(FARPROC)SubDialogProc);
|
|
State=STATE_RECURS;
|
|
#else
|
|
#ifdef RESIZE_DIALOG
|
|
GetWindowRect(GetParent(hWnd),&rect);
|
|
rect.right++;
|
|
SetWindowPos(GetParent(hWnd),0,0,0,
|
|
rect.right-rect.left,rect.bottom-rect.top,
|
|
SWP_NOMOVE|SWP_NOZORDER);
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
State=OldState; Rec--;
|
|
return lResult;
|
|
}
|
|
|
|
/* MAIN DIALOG PROCEDURE */
|
|
BOOL FAR CALLBACK _export TestDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL bResult=0;
|
|
RECT rect;
|
|
int OldState=State;
|
|
int But=-1;
|
|
|
|
State=STATE_RECURS; Rec++;
|
|
if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam,"dlgp");
|
|
switch (msg) {
|
|
case WM_INITDIALOG:
|
|
hDialog = hWndDlg;
|
|
/* subclass dialog window proc */
|
|
wndDialog = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
Logf("dialog visible=%s",IsWindowVisible(hWndDlg)?"TRUE":"FALSE");
|
|
/* subclass OK button */
|
|
hButton[3] = GetDlgItem(hWndDlg,IDOK);
|
|
wndButton[3] = (WNDPROC)SetWindowLong(hButton[3],GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
/* subclass group box */
|
|
hGroup = GetDlgItem(hWndDlg,IDC_GROUPBOX1);
|
|
wndGroup = (WNDPROC)SetWindowLong(hGroup,GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
|
|
#ifdef RESIZE_DIALOG
|
|
GetWindowRect(hWndDlg,&rect);
|
|
rect.right--;
|
|
SetWindowPos(hWndDlg,0,0,0,
|
|
rect.right-rect.left,rect.bottom-rect.top,
|
|
SWP_NOMOVE|SWP_NOZORDER);
|
|
// ShowWindow(GetDlgItem(hWndDlg,IDCANCEL),SW_HIDE);
|
|
#endif
|
|
|
|
bResult=TRUE; /* we don't do SetFocus */
|
|
break;
|
|
case WM_PAINT:
|
|
PaintPattern(hWndDlg);
|
|
bResult=TRUE;
|
|
break;
|
|
case WM_COMMAND:
|
|
EndDialog(hWndDlg,LOWORD(wParam));
|
|
bResult=TRUE;
|
|
break;
|
|
case WM_CLOSE:
|
|
EndDialog(hWndDlg,IDCANCEL);
|
|
bResult=TRUE;
|
|
break;
|
|
case WM_NCDESTROY:
|
|
hDialog = 0;
|
|
break;
|
|
}
|
|
State=OldState; Rec--;
|
|
return bResult;
|
|
}
|
|
|
|
/* SUBDIALOG PROCEDURE */
|
|
BOOL FAR CALLBACK _export SubDialogProc(HWND hWndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL bResult=0;
|
|
RECT rect;
|
|
int OldState=State;
|
|
int But=-1;
|
|
|
|
State=STATE_RECURS; Rec++;
|
|
if (!Clicked) LogMessage(OldState,hWndDlg,msg,wParam,lParam,NULL);
|
|
switch (msg) {
|
|
case WM_INITDIALOG:
|
|
hSubDlg = hWndDlg;
|
|
/* subclass dialog window proc */
|
|
wndSubDlg = (WNDPROC)SetWindowLong(hDialog,GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
|
|
bResult=TRUE; /* we don't do SetFocus */
|
|
break;
|
|
case WM_NCDESTROY:
|
|
hSubDlg = 0;
|
|
break;
|
|
}
|
|
State=OldState; Rec--;
|
|
return bResult;
|
|
}
|
|
|
|
/********************/
|
|
/*** MAIN PROGRAM ***/
|
|
/********************/
|
|
|
|
BOOL AppInit(void)
|
|
{
|
|
WNDCLASS wclass;
|
|
|
|
wclass.style = CS_HREDRAW|CS_VREDRAW;
|
|
wclass.lpfnWndProc = MainWindowProc;
|
|
wclass.cbClsExtra = 0;
|
|
wclass.cbWndExtra = 0;
|
|
wclass.hInstance = hInst;
|
|
wclass.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(1));
|
|
wclass.hCursor = LoadCursor(0,IDC_ARROW);
|
|
wclass.hbrBackground = GetStockObject(WHITE_BRUSH);
|
|
wclass.lpszMenuName = NULL;
|
|
wclass.lpszClassName = wclassname;
|
|
if (!RegisterClass(&wclass)) return FALSE;
|
|
wclass.lpfnWndProc = SubWindowProc;
|
|
wclass.lpszClassName = wcclassname;
|
|
if (!RegisterClass(&wclass)) return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
LPSTR lpszCmdLine, int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
RECT rect;
|
|
|
|
hInst = hInstance;
|
|
if (!hPrevInstance)
|
|
if (!AppInit())
|
|
return 0;
|
|
|
|
StartTime=GetTickCount();
|
|
hListBox = CreateWindow("LISTBOX","Messages",WS_BORDER|WS_VSCROLL|WS_CHILD|
|
|
LBS_HASSTRINGS|LBS_NOTIFY|LBS_WANTKEYBOARDINPUT,
|
|
0,0,0,0,GetDesktopWindow(),0,hInst,0);
|
|
if (!hListBox) {
|
|
MessageBox(0,"Could not create list box","Error",MB_OK);
|
|
}
|
|
|
|
State=STATE_CREATE;
|
|
hMainWnd = CreateWindowEx(MAIN_EXSTYLE,wclassname,winname,MAIN_STYLE,
|
|
CW_USEDEFAULT,0,400,300,0,0,hInst,0);
|
|
if (!hMainWnd) return 0;
|
|
State=STATE_SHOW;
|
|
ShowWindow(hMainWnd,nCmdShow);
|
|
#ifdef TEST_DESTROY_MAIN
|
|
State=STATE_DESTROY;
|
|
DestroyWindow(hMainWnd);
|
|
State=STATE_DIRECT;
|
|
while (GetMessage(&msg,0,0,0)) {
|
|
TranslateMessage(&msg);
|
|
State=STATE_DISPATCH;
|
|
DispatchMessage(&msg);
|
|
State=STATE_DIRECT;
|
|
}
|
|
State=STATE_CREATE;
|
|
hMainWnd = CreateWindowEx(MAIN_EXSTYLE,wclassname,winname,MAIN_STYLE,
|
|
CW_USEDEFAULT,0,400,300,0,0,hInst,0);
|
|
if (!hMainWnd) return 0;
|
|
State=STATE_SHOW;
|
|
ShowWindow(hMainWnd,nCmdShow);
|
|
#endif
|
|
/* update, so no WM_PAINTs are pending */
|
|
State=STATE_UPDATE;
|
|
// UpdateWindow(hMainWnd);
|
|
Ready=TRUE;
|
|
/* fill client area with a pattern */
|
|
FillPattern(hMainWnd,0);
|
|
/* create subwindow */
|
|
State=STATE_CREATE;
|
|
GetClientRect(hMainWnd,&rect);
|
|
hSubWnd = CreateWindow(wcclassname,winname,WS_CHILD|WS_BORDER|WS_CLIPSIBLINGS,
|
|
0,rect.bottom/2,rect.right,rect.bottom-(rect.bottom/2),hMainWnd,0,hInst,0);
|
|
if (!hSubWnd) return 0;
|
|
/* create buttons */
|
|
hButton[0] = CreateWindow("BUTTON","1",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
|
|
8,8,48,20,hMainWnd,0,hInst,0);
|
|
hButton[1] = CreateWindow("BUTTON","2",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
|
|
32,12,48,20,hMainWnd,0,hInst,0);
|
|
hButton[2] = CreateWindow("BUTTON","3",WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE,
|
|
56,16,48,20,hMainWnd,0,hInst,0);
|
|
/* subclass them */
|
|
wndButton[0] = (WNDPROC)SetWindowLong(hButton[0],GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
wndButton[1] = (WNDPROC)SetWindowLong(hButton[1],GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
wndButton[2] = (WNDPROC)SetWindowLong(hButton[2],GWL_WNDPROC,(LONG)SubClassWindowProc);
|
|
/* show them */
|
|
State=STATE_UPDATE;
|
|
UpdateWindow(hButton[0]);
|
|
LogChildOrder(hMainWnd);
|
|
Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
|
|
|
|
/* now reparent the button to our (invisible) subwindow */
|
|
State=STATE_TEST;
|
|
/* in different order, seeing who gets topmost */
|
|
SetParent(hButton[0],hSubWnd);
|
|
SetParent(hButton[2],hSubWnd);
|
|
SetParent(hButton[1],hSubWnd);
|
|
LogChildOrder(hSubWnd);
|
|
/* the button should now be invisible */
|
|
Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
|
|
/* see if we can draw on them */
|
|
FillPattern(hButton[0],0);
|
|
|
|
#ifdef SHOW_SUB
|
|
State=STATE_SHOW;
|
|
ShowWindow(hSubWnd,SW_SHOWNORMAL);
|
|
State=STATE_UPDATE;
|
|
UpdateWindow(hSubWnd);
|
|
FillPattern(hSubWnd,0);
|
|
// InvalidateRect(hMainWnd,NULL,TRUE);
|
|
Logf("but1 visible=%d",IsWindowVisible(hButton[0]));
|
|
#endif
|
|
|
|
#ifdef TEST_DIALOG
|
|
State=STATE_DIALOG;
|
|
DialogBox(hInst,MAKEINTRESOURCE(1),hMainWnd,(FARPROC)TestDialogProc);
|
|
#endif
|
|
#ifdef TEST_COMMCTL
|
|
{
|
|
DWORD arr[16];
|
|
CHOOSECOLOR cc={sizeof(cc),0,hInst,0,arr,0};
|
|
ChooseColor(&cc);
|
|
}
|
|
#endif
|
|
|
|
State=STATE_DIRECT;
|
|
while (GetMessage(&msg,0,0,0)) {
|
|
TranslateMessage(&msg);
|
|
State=STATE_DISPATCH;
|
|
DispatchMessage(&msg);
|
|
State=STATE_DIRECT;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|