The Windows GUI behaviour tester used on the Windows computer. It was
used with Borland C++ 4.52, but should be easy to adapt to Winelib by whoever feels like it; I haven't, I just released this useful test app in case it would benefit other developers.
This commit is contained in:
parent
e9b568c0c5
commit
eb42128790
|
@ -0,0 +1,686 @@
|
||||||
|
/* 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
|
||||||
|
#undef TEST_DESTROY_MAIN
|
||||||
|
#undef SHOW_SUB
|
||||||
|
#define 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_NCLBUTTONDOWN)
|
||||||
|
MSG(WM_NCLBUTTONUP)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
/* 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=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);
|
||||||
|
char*name;
|
||||||
|
static char buffer[256];
|
||||||
|
|
||||||
|
strcpy(buffer,"child list:");
|
||||||
|
while (hWndChild) {
|
||||||
|
strcat(strcat(buffer," "),WndName(hWndChild));
|
||||||
|
hWndChild=GetWindow(hWndChild,GW_HWNDNEXT);
|
||||||
|
}
|
||||||
|
Log(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogMessage(int state,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,char*name=NULL)
|
||||||
|
{
|
||||||
|
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),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));
|
||||||
|
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)));
|
||||||
|
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;
|
||||||
|
default:
|
||||||
|
#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=0)
|
||||||
|
{
|
||||||
|
HDC dc=pdc?pdc:GetDC(hWnd);
|
||||||
|
HBRUSH oldbrush;
|
||||||
|
RECT rect;
|
||||||
|
if (!dc) {
|
||||||
|
Logf("failed to acquire DC for window %s",WndName(hWnd));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Logf("acquired DC for %s window %s, painting",
|
||||||
|
IsWindowVisible(hWnd)?"visible":"invisible",WndName(hWnd));
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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 = CreateWindow(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 = CreateWindow(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);
|
||||||
|
/* 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]);
|
||||||
|
|
||||||
|
#ifdef SHOW_SUB
|
||||||
|
State=STATE_SHOW;
|
||||||
|
ShowWindow(hSubWnd,SW_SHOWNORMAL);
|
||||||
|
State=STATE_UPDATE;
|
||||||
|
UpdateWindow(hSubWnd);
|
||||||
|
FillPattern(hSubWnd);
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
GUITEST.RC
|
||||||
|
|
||||||
|
produced by Borland Resource Workshop
|
||||||
|
|
||||||
|
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "guitest.rh"
|
||||||
|
|
||||||
|
1 ICON
|
||||||
|
{
|
||||||
|
'00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02'
|
||||||
|
'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
|
||||||
|
'00 00 01 00 04 00 00 00 00 00 80 02 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
|
||||||
|
'00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 80 80'
|
||||||
|
'80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
|
||||||
|
'00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0A'
|
||||||
|
'A0 00 00 00 00 00 AA A0 00 00 00 00 00 00 00 00'
|
||||||
|
'A0 0A AA A0 00 AA 00 0A 00 00 00 A0 A0 00 00 00'
|
||||||
|
'A0 0A 00 00 0A A0 00 0A 00 00 00 A0 00 00 00 00'
|
||||||
|
'A0 0A 00 00 AA 00 00 0A 00 00 0A A0 0A 00 00 00'
|
||||||
|
'A0 0A 00 00 00 00 00 A0 00 00 0A 00 0A 00 22 22'
|
||||||
|
'A2 2A 22 22 22 2A AA 22 22 22 2A 22 2A 22 22 22'
|
||||||
|
'AA 2A AA A2 22 A2 22 22 22 22 2A 22 2A 22 00 00'
|
||||||
|
'0A 0A 00 00 00 A0 00 00 00 00 0A 00 0A 00 00 00'
|
||||||
|
'0A 0A 00 00 00 A0 00 00 00 00 0A 00 0A 00 00 00'
|
||||||
|
'0A 00 A0 00 00 AA 00 00 00 00 0A 00 0A 00 00 00'
|
||||||
|
'0A 00 AA A0 00 0A AA A0 0A AA AA AA 00 00 0A AA'
|
||||||
|
'AA AA A0 00 00 00 00 00 00 00 00 0A A0 00 0A 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 77 70 70 00 77 77 00 07 00 00 00 00 00 00'
|
||||||
|
'00 07 00 07 07 07 00 00 70 70 70 00 00 00 00 00'
|
||||||
|
'00 70 77 70 07 70 77 77 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 70 07 07 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 70 77 07 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 77 00 07 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 70 77 70 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 70 00 70 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 70 77 77 07 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 07 00 00 70 70 70 07 07 70 70 00 00 00 00 00'
|
||||||
|
'00 00 77 77 00 07 00 00 70 07 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
|
||||||
|
'00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF'
|
||||||
|
'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF'
|
||||||
|
'FF FF E7 FF 1F FF F6 1C EF D7 F6 F9 EF DF F6 F3'
|
||||||
|
'EF 9B F6 FF DF BB 00 00 00 00 00 00 00 00 FA FD'
|
||||||
|
'FF BB FA FD FF BB FB 7C FF BB FB 1E 18 0F 80 7F'
|
||||||
|
'FF E7 BF FF FF FF FF 17 0E FF FE 02 04 7F FC 00'
|
||||||
|
'00 7F FC 60 60 7F FC 40 60 7F FC 00 60 7F FC 44'
|
||||||
|
'60 7F FC 74 60 7F FC 00 60 7F FE 04 60 7F FF 0E'
|
||||||
|
'F6 FF FF FF FF FF FF FF FF FF FF FF FF FF'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1 DIALOG 6, 15, 196, 119
|
||||||
|
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||||
|
CAPTION "Test Dialog"
|
||||||
|
FONT 8, "MS Sans Serif"
|
||||||
|
{
|
||||||
|
DEFPUSHBUTTON "OK", IDOK, 12, 96, 50, 14
|
||||||
|
PUSHBUTTON "Cancel", IDCANCEL, 72, 96, 50, 14
|
||||||
|
PUSHBUTTON "Help", IDHELP, 132, 96, 50, 14
|
||||||
|
GROUPBOX "Group", IDC_GROUPBOX1, 4, 4, 188, 84, BS_GROUPBOX | WS_GROUP | WS_TABSTOP
|
||||||
|
}
|
||||||
|
|
||||||
|
2 DIALOG 6, 15, 180, 72
|
||||||
|
STYLE WS_CHILD | WS_VISIBLE | WS_BORDER
|
||||||
|
FONT 8, "MS Sans Serif"
|
||||||
|
{
|
||||||
|
AUTOCHECKBOX "Checkbox 1", IDC_CHECKBOX1, 8, 8, 80, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
|
||||||
|
AUTOCHECKBOX "Checkbox 2", IDC_CHECKBOX2, 8, 28, 80, 12
|
||||||
|
AUTOCHECKBOX "Checkbox 3", IDC_CHECKBOX3, 8, 48, 60, 12
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
guitest.rh
|
||||||
|
|
||||||
|
produced by Borland Resource Workshop
|
||||||
|
|
||||||
|
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define IDC_CHECKBOX1 104
|
||||||
|
#define IDC_CHECKBOX2 105
|
||||||
|
#define IDC_CHECKBOX3 106
|
||||||
|
#define DIALOG_2 2
|
||||||
|
#define IDC_GROUPBOX1 10
|
||||||
|
#define DIALOG_1 1
|
||||||
|
#define ICON_1 1
|
Loading…
Reference in New Issue