1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/controls/button.c
Alexandre Julliard 8d24ae6d31 Release 940405
Tue Apr  5 14:36:59 1994  Bob Amstadt  (bob@pooh)

	* [include/mdi.h] [windows/mdi.c]
	Use WM_PARENTNOTIFY messages to activate children.
	Generate WM_CHILDACTIVATE messages.
	Beginnings handler for maxmized child window.
	Clean up when children are destroyed.

	* [windows/message.c] [windows/nonclient.c] [windows/winpos.c]
	Removed code add 94/03/26.

Apr 4, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [control/menu.c]
	Make mouse menu navigation working again. :-))
	(be carefull, clicking outside menus (ie.: clientrect) 
	not resolved yet)

	* [windows/nonclient.c]  [controls/scroll.c]
	Bugs fix in NCTrackScrollBars().

	* [misc/dos_fs.c]
	Bug fix in 'ToDos()' in conversion for '/',
		(example: '/window/' was translated to 'WINDOWs').

	* [miscemu/int21.c]
	Function ChangeDir() extract possible drive before DOS_ChangeDir().

	* [loader/library.c]  [loader/wine.c]
	Playing around moving function GetProcAddress() and put some code in.

Mon Apr  4 21:39:07 1994  Alexandre Julliard (julliard@lamisun.epfl.ch)

	* [misc/main.c]
	Better explanation of command-line options.

	* [objects/dib.c]
	Implemented SetDIBitsToDevice().

	* [windows/dc.c]
	Bug fix in SetDCState().

	* [windows/event.c]
	Removed WS_DISABLED handling (now done in message.c).

	* [windows/message.c]
	Added sending a WM_PARENTNOTIFY message in MSG_TranslateMouseMsg().
	Use WindowFromPoint() to find the window for mouse events, taking
	into account disabled windows.

	* [windows/painting.c]
	Bug fix in BeginPaint() to allow calling it at other times than
	on WM_PAINT (Solitaire needs it...)

	* [windows/win.c]
	Implemented FindWindow().
	Rewritten EnableWindow() to behave more like Windows.

	* [windows/winpos.c]
	Rewritten WindowFromPoint() to also search child windows.

Mon Apr  4 17:36:32 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [include/int21.h] -> [msdos.h]
	renamed.

	* [miscemu/int10.h] [miscemu/int25.h] [miscemu/int26.h] 
	new, added for int 10, 25 and 26.

	* [miscemu/ioports.c]
	new, added to allow win apps to use ioports.

	* [loader/signal.c]
	Added support for in, inb, out, outb instructions.

Sun Mar 27 13:40:25 1994  Bob Amstadt  (bob@pooh)

	* controls/menu.c (InsertMenu): Changed to use FindMenuItem().

Sat Mar 26 21:23:55 1994  Bob Amstadt  (bob@pooh)

	* [windows/mdi.c]
	Window list properly updated.

	* [windows/message.c]
	Call WINPOS_ChildActivate() when mouse pressed.

	* [windows/nonclient.c]
	Use WINPOS_IsAnActiveWindow() instead of GetActiveWindow() in
	NC_HandleNCPaint().

	* [windows/winpos.c]
	Created functions WINPOS_IsAnActiveWindow() and WINPOS_ActivateChild()

Thu Mar 24 14:49:17 1994  Bob Amstadt  (bob@pooh)

	* controls/menu.c (DeleteMenu): Changed to use FindMenuItem
	(DeleteMenu): Many bug fixes.

	* [controls/menu.c]
	Created function FindMenuItem().

Thu Mar 24 14:17:24 1994  Bob Amstadt  (bob@pooh)

	* [windows/win.c]
	Removed incorrect MDI handling code from CreateWindowEx().

	* [controls/menu.c]
	MF_STRING items needed to allocate a private copy of string.

	* [controls/menu.c]
	Fixed buggy calls to GlobalFree().

	* [memory/global.c]
	Eliminated some redundant code with function call.

Wed Mar 23 1994 Pentti Moilanen (pentti.moilanen@ntc.nokia.com)

	* [windows/timer.c]
	timer list pointers looped in InsertTimer

Tue Mar 29 13:32:08 MET DST 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [misc/cursor.c]
	A few changes for desktop window support.

	* [misc/main.c]
	Added -depth option.

	* [misc/rect.c]
	Yet another bug fix in SubtractRect().

	* [objects/bitmap.c]
	Changes to use only one depth (specified with -depth)
	for color bitmaps.

	* [objects/brush.c]
	Added support for dithered solid brushes.

	* [objects/color.c]
	Use the same 20 system colors as in Windows.
	System palette initialisation now done in COLOR_InitPalette().
	Added support for a color mapping table to map logical color
	indexes to X colormap entries.
	Implemented GetNearestColor() and RealizeDefaultPalette().

	* [objects/dib.c]
	Added support for color mapping table.

	* [objects/dither.c]  (New file)
	Implemented solid color dithering.

	* [objects/palette.c]
	Implemented GetSystemPaletteEntries() and SelectPalette().

	* [windows/class.c]
	Make a copy of the menu name in RegisterClass().

	* [windows/dc.c]
	Fixed device caps when using a desktop window.
	Added support for the color mapping table in DCs.

	* [windows/event.c]
	Added ConfigureNotify handler on desktop window.

	* [windows/message.c]
	Removed call to XTranslateCoordinates() on every mouse motion
	New function MSG_Synchronize() to synchronize with the X server.

	* [windows/syscolor.c]
	Rewritten SYSCOLOR_Init() to read the system colors from WIN.INI.

	* [windows/winpos.c]
	Added synchronization on window mapping. Solves the double redraw
	problem when starting Solitaire.

Mar 27, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [control/menu.c]	* [windows/defwnd.c]
	Make keyboard navigation working with menubar,
	but temporarely inserted a bug in menubar mouse handling ... :-((
	(it will be fix next week !)

	* [windows/defwnd.c]
	Connect VK_MENU to menubar navigation.

	* [loader/library.c]
	GetModuleHandle() return 'fictive 0xF000+ handles' for built-in DLLs.

Sun Mar 20 22:32:13 1994 Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/main.c]
	Added Copy(). Added a check for `-h' to show usage.

	* [misc/dos_fs.c]
	Fixed bug in FindFile(), to load directories as dlls.

	* [misc/dos_fs.c]
	Fixed ToUnix() and ToDos() again, as my previous patch
	didn't make it.

	* [misc/dos_fs.c] [miscemu/int21.c]
	Bug fixes, should be able to handle all winfile and progman int21
	requests now except for a few small things.

Tue Mar 29 06:25:54 1994  crw@harris.mlb.semi.harris.com (Carl Williams)

	* [memory/heap.c]
	Implemented GetFreeSystemResources().

Mon Mar 21 17:32:25 1994  Bob Amstadt  (bob@pooh)

	* controls/menu.c (GetSubMenu): Function did not return correct value

	* [windows/mdi.c]
	Beginnings of menu handling.

Thu Mar 10 11:32:06 1994  Stefan (SAM) Muenzel  (muenzel@tat.physik.uni-tuebingen.de)

	* [objects/font.c]
	if font.width equals zero use asterix instead.

Mon Mar 21 17:23:37 MET 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [objects/bitmap.c]
	Rewritten bitmap code to use exclusively X pixmaps; *much* faster.

	* [objects/brush.c]
	Some changes with pattern brushes because of the new bitmap code.

	* [objects/color.c]
	Added function COLOR_ToPhysical for better color mapping.

	* [objects/dib.c]
	Heavily optimized SetDIBits().

	* [windows/dc.c]
	Opimized SetDCState() and DC_SetupGC*() functions.
	Added stub for CreateIC().

Mar 20, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [misc/message.c]
	Call SetFocus() after closing box to give back focus to previous owner.

	* [misc/files.c]
	Small bug fix in GetTempFilename() : replace a '\' to '\\'.

	* [control/scroll.c]
	Calls to BitBlt() replace by StretchBlt().

	* [control/menu.c]
	Call SetFocus() to previous owner after closing Popups.	
	Fill stub DeleteMenu().

	* [control/listbox.c]
	* [control/combo.c]
	Use SetFocus() in WM_LBUTTONDOWN.
	Close ComboBox List upon WM_KILLFOCUS.
	Early development of WM_MEASUREITEM mecanism.

	* [windows/defwnd.c]
	Early development of WM_MEASUREITEM mecanism.

Tue Mar 22 10:44:57 1994  Miguel de Icaza  (miguel@xochitl)

	* [misc/atom.c]
	Fixed sintaxis problem when building the library.

Tue Mar 15 13:11:56 1994  Bob Amstadt  (bob@pooh)

	* [include/windows.h]
	Added message types and structures for MDI

	* [include/mdi.h]
	Created internal structures for handling MDI

	* [windows/mdi.c]
	Began creating MDI support

Thu Mar 10 16:51:46 1994  Bob Amstadt  (bob@pooh)

	* [loader/wine.c] [include/wine.h]
	Added new field to "struct w_files" to hold the "name table"
	resource for Windows 3.0 programs

	* [loader/resource.c]
	Added code to handle programs with a "name table" resource.
	LoadResourceByName() modified to check for the existence of
	this resource.

Mon Mar 14 22:31:42 MET 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [objects/color.c]
	Added installing the private colormap on the desktop window.

	* [windows/event.c]
	Cleaned up focus event handling (see focus.c).
	Use GetFocus() to direct key events to the correct window.

	* [windows/focus.c]
	Rewritten SetFocus() to:
	- only set X focus on top-level windows
	- send WM_SETFOCUS and WM_KILLFOCUS messages (was done in event.c)
	- prevent setting focus to disabled windows
	- install private colormap so -privatemap option works again

	* [windows/message.c] [windows/timer.c]
	Changed timer management to no longer use PostMessage(), but
	to generate timer messages on the fly. Also fixed a related bug
	in GetMessage() which could cause busy-waiting.

	* [windows/win.c]
	Only select focus events on top-level windows.

	* [windows/winpos.c]
	Added some sanity checks for desktop window.

Fri Mar  4 20:42:01 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/dos_fs.c]
	bug fixes in ToUnix(), WinIniFileName(), GetUnixFileName(). 
	Support for tilde symbol added for rootdirectories in [drives]
	section of wine's configfile.

	* [misc/file.c]
	hread(), hwrite() added.

	* [misc/main.c]
	hmemcpy() added.

	* [if1632/stress.spec] [include/stress.h] [misc/stress.c]
	Added STRESS.DLL, an useless dll used to stress a windows system.

	* [*/*]
	Added missing #includes, fixed prototypes for prototype checking.

	* [include/prototypes.h]

	Added prototypes for loader/*c, if1632/*c.

Tue Mar  8 09:54:34 1994  Bob Amstadt  (bob@pooh)

	* [Configure]
	Added reminder to set WINEPATH, if it is not set.

	* [Imakefile]
	Removed #elif's

	* [controls/button.c]
	Added BN_CLICKED notification for owner-draw buttons.

	* [if1632/kernel.spec] [memory/heap.c]
	Changed Local* functions to WIN16_Local* to prevent unconcious use
	of these functions.

	* [if1632/relay.c]
	Push old Stack16Frame on stack before setting.

	* [include/atom.h] [misc/atom.c] [include/heap.h] [memory/local.c]
	Added multiple local heap handling in Atom* functions.

	* [include/regfunc.h] [miscemu/int21.c]
	Rewrote DOS3Call() use context frame that is already on the stack.

	* [misc/profile.c]
	Fixed to allow leading ";" to mark comments.

	* [misc/spy.c]
	Fixed bugs and added support for "include" and "exclude" filters.

	* [misc/user.c]
	Rearranged calls in InitApp().

	* [misc/font.c]
	Fixed font handling to create system fonts, if they are used.

	* [windows/dc.c]
	If text drawn on window with no font specified, then default the
	font to the system font.

Mon Mar  7 20:32:09 MET 1994  julliard@di.epfl.ch (Alexandre Julliard)

	* [controls/desktop.c]
	Added handling of WM_NCCREATE and WM_ERASEBKGND functions.
	Implemented SetDeskPattern().

	* [misc/main.c]
	Added -desktop option to get a large desktop window with
	everything inside it.
	Added -name option.

	* [misc/rect.c]
	Bug fix in SubtractRect().

	* [objects/*.c]
	Replaced the DefaultRootWindow() macro by the rootWindow variable.

	* [windows/event.c] [windows/message.c]
	  [windows/nonclient.c] [windows/win.c]
	A few changes to accomodate the new desktop window.

 Tue Mar  8 11:13:03 1994  Miguel de Icaza  (miguel@xochitl.nuclecu.unam.mx)
 
 	* [toolkit/arch.c] --New file-- 
 	Routines for converting little endian data structures to
 	big-endian data structures, currently only BITMAP structures are 
 	converted.
 
 	* [misc/atom.c]
 	When used as part of the WineLib, the code is much simpler.
 	Doesn't depend on alignement.
 
 	* [loader/wine.c]
 	Ifdefed Emulator dependent code if compiling WineLib.
 
 	* [loader/resource.c]
 	Moved misc/resource.c to loader/resource.c.
 
 	* [loader/dump.c,ldt.c,ldtlib.c,library,c,selector.c,signal.c]
 	Ifdefed whole code if compiling WINELIB.
 
 	* [include/winsock.h]
 	Added compilation define to allow compilation on SunOS.
 
 	* [include/wine.h]
 	Removed load_typeinfo and load_nameinfo prototypes, they belong
 	to neexe.h
 
 	* [include/neexe.h]
 	Added load_typeinfo and load_nameinfo prototypes.
 
 	* [include/arch.h]
 	Fixed some bugs in the conversion routines.
 	Added macros for Bitmap loading.

Tue Mar  8 12:52:05 1994  crw@maniac.mlb.semi.harris.com (Carl Williams)
 	
	* [if1632/kernel.spec] [memory/global.c]
	Implemented GetFreeSpace()

	* [if1632/user.spec] [loader/resource.c]
	Implemented CreateIcon()
1994-04-05 21:42:43 +00:00

1067 lines
26 KiB
C

/* File: button.c -- Button type widgets
*
* Copyright (C) 1993 Johannes Ruscheinski
* Copyright (C) 1993 David Metcalfe
*/
static char Copyright1[] = "Copyright Johannes Ruscheinski, 1993";
static char Copyright2[] = "Copyright David Metcalfe, 1993";
#include <windows.h>
#include "win.h"
#include "user.h"
LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
static COLORREF color_windowtext, color_windowframe, color_btnface,
color_btnshadow, color_btntext, color_btnhighlight;
static BOOL pressed;
#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
#define DIM(array) ((sizeof array)/(sizeof array[0]))
static LONG PB_Paint(HWND hWnd);
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG PB_KillFocus(HWND hwnd);
static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc);
static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc);
static LONG CB_Paint(HWND hWnd);
static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG CB_KillFocus(HWND hWnd);
static LONG CB_SetCheck(HWND hWnd, WORD wParam);
static LONG CB_GetCheck(HWND hWnd);
static LONG RB_Paint(HWND hWnd);
static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
static LONG RB_KillFocus(HWND hWnd);
static LONG RB_SetCheck(HWND hWnd, WORD wParam);
static LONG RB_GetCheck(HWND hWnd);
static LONG GB_Paint(HWND hWnd);
static LONG UB_Paint(HWND hWnd);
static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG UB_KillFocus(HWND hWnd);
static LONG OB_Paint(HWND hWnd);
static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
static LONG OB_KillFocus(HWND hWnd);
typedef struct
{
LONG (*paintfn)();
LONG (*lButtonDownfn)();
LONG (*lButtonUpfn)();
LONG (*lButtonDblClkfn)();
LONG (*killFocusfn)();
LONG (*setCheckfn)();
LONG (*getCheckfn)();
} BTNFN;
#define MAX_BTN_TYPE 12
static BTNFN btnfn[MAX_BTN_TYPE] =
{
{
(LONG(*)())PB_Paint, /* BS_PUSHBUTTON */
(LONG(*)())PB_LButtonDown,
(LONG(*)())PB_LButtonUp,
(LONG(*)())PB_LButtonDblClk,
(LONG(*)())PB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */
(LONG(*)())PB_LButtonDown,
(LONG(*)())PB_LButtonUp,
(LONG(*)())PB_LButtonDblClk,
(LONG(*)())PB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())CB_Paint, /* BS_CHECKBOX */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())RB_Paint, /* BS_RADIOBUTTON */
(LONG(*)())RB_LButtonDown,
(LONG(*)())RB_LButtonUp,
(LONG(*)())RB_LButtonDblClk,
(LONG(*)())RB_KillFocus,
(LONG(*)())RB_SetCheck,
(LONG(*)())RB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_3STATE */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())CB_Paint, /* BS_AUTO3STATE */
(LONG(*)())CB_LButtonDown,
(LONG(*)())CB_LButtonUp,
(LONG(*)())CB_LButtonDblClk,
(LONG(*)())CB_KillFocus,
(LONG(*)())CB_SetCheck,
(LONG(*)())CB_GetCheck
},
{
(LONG(*)())GB_Paint, /* BS_GROUPBOX */
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())UB_Paint, /* BS_USERBUTTON */
(LONG(*)())UB_LButtonDown,
(LONG(*)())UB_LButtonUp,
(LONG(*)())NULL,
(LONG(*)())UB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())RB_Paint, /* BS_AUTORADIOBUTTON */
(LONG(*)())RB_LButtonDown,
(LONG(*)())RB_LButtonUp,
(LONG(*)())RB_LButtonDblClk,
(LONG(*)())RB_KillFocus,
(LONG(*)())RB_SetCheck,
(LONG(*)())RB_GetCheck
},
{
(LONG(*)())NULL, /* Not defined */
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL,
(LONG(*)())NULL
},
{
(LONG(*)())OB_Paint, /* BS_OWNERDRAW */
(LONG(*)())OB_LButtonDown,
(LONG(*)())OB_LButtonUp,
(LONG(*)())NULL,
(LONG(*)())OB_KillFocus,
(LONG(*)())NULL,
(LONG(*)())NULL
},
};
LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
{
LONG lResult = 0;
HDC hDC;
RECT rc;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style = wndPtr->dwStyle & 0x0000000F;
switch (uMsg) {
/* case WM_GETDLGCODE:
lResult = DLGC_BUTTON;
break;
*/
case WM_ENABLE:
InvalidateRect(hWnd, NULL, FALSE);
break;
case WM_CREATE:
if (style < 0L || style >= (LONG)DIM(btnfn))
lResult = -1L;
else
{
/* initialise colours used for button rendering: */
color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
color_btnface = GetSysColor(COLOR_BTNFACE);
color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
color_btntext = GetSysColor(COLOR_BTNTEXT);
color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
(WORD)(*(wndPtr->wExtra)) = 0;
pressed = FALSE;
lResult = 0L;
}
break;
case WM_PAINT:
if (btnfn[style].paintfn)
(btnfn[style].paintfn)(hWnd);
break;
case WM_LBUTTONDOWN:
if (btnfn[style].lButtonDownfn)
(btnfn[style].lButtonDownfn)(hWnd, wParam, lParam);
break;
case WM_LBUTTONUP:
if (btnfn[style].lButtonUpfn)
(btnfn[style].lButtonUpfn)(hWnd, wParam, lParam);
break;
case WM_LBUTTONDBLCLK:
if (btnfn[style].lButtonDblClkfn)
(btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
break;
case WM_SETFOCUS:
break;
case WM_KILLFOCUS:
if (btnfn[style].killFocusfn)
(btnfn[style].killFocusfn)(hWnd);
break;
case WM_SYSCOLORCHANGE:
color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
color_btnface = GetSysColor(COLOR_BTNFACE);
color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
color_btntext = GetSysColor(COLOR_BTNTEXT);
color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
InvalidateRect(hWnd, NULL, TRUE);
break;
case BM_SETCHECK:
if (btnfn[style].setCheckfn)
(btnfn[style].setCheckfn)(hWnd, wParam);
break;
case BM_GETCHECK:
if (btnfn[style].getCheckfn)
return (btnfn[style].getCheckfn)(hWnd);
break;
default:
lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
GlobalUnlock(hWnd);
return lResult;
}
/**********************************************************************
* Push Button Functions
*/
static LONG PB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
if (pressed)
DrawPressedPushButton(hDC, hWnd, rc);
else
DrawRaisedPushButton(hDC, hWnd, rc);
EndPaint(hWnd, &ps);
}
static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
pressed = FALSE;
ReleaseCapture();
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
}
static LONG PB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
{
HPEN hOldPen, hFramePen;
HBRUSH hOldBrush, hShadowBrush, hHighlightBrush, hBackgrndBrush;
HRGN rgn1, rgn2, rgn;
int len;
static char text[50+1];
POINT points[6];
DWORD dwTextSize;
int delta;
TEXTMETRIC tm;
int i;
hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
hBackgrndBrush = CreateSolidBrush(color_btnface);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
SetBkMode(hDC, TRANSPARENT);
rgn = CreateRectRgn(0, 0, 0, 0);
rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hButton, CTLCOLOR_BTN));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
/* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text);
if (len >= 1) {
rc.left--; rc.bottom--;
DrawText(hDC, text, len, &rc,
DT_SINGLELINE | DT_CENTER| DT_VCENTER);
}
/* draw button highlight */
points[0].x = rc.left+2;
points[0].y = rc.bottom;
points[1].x = rc.left+4;
points[1].y = rc.bottom-2;
points[2].x = rc.left+4;
points[2].y = rc.top+3;
points[3].x = rc.right-3;
points[3].y = rc.top+3;
points[4].x = rc.right-1;
points[4].y = rc.top+1;
points[5].x = rc.left+2;
points[5].y = rc.top+1;
hHighlightBrush = CreateSolidBrush(color_btnhighlight);
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND);
FillRgn(hDC, rgn2, hHighlightBrush);
/* draw button shadow: */
points[0].x = rc.left+2;
points[0].y = rc.bottom;
points[1].x = rc.left+4;
points[1].y = rc.bottom-2;
points[2].x = rc.right-3;
points[2].y = rc.bottom-2;
points[3].x = rc.right-3;
points[3].y = rc.top+3;
points[4].x = rc.right-1;
points[4].y = rc.top;
points[5].x = rc.right-1;
points[5].y = rc.bottom;
hShadowBrush = CreateSolidBrush(color_btnshadow);
rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
CombineRgn(rgn, rgn1, rgn2, RGN_AND);
FillRgn(hDC, rgn2, hShadowBrush);
/* do we have the focus? */
if (len >= 1 && GetFocus() == hButton) {
dwTextSize = GetTextExtent(hDC, text, len);
delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
rc.left += delta; rc.right -= delta;
GetTextMetrics(hDC, &tm);
delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
rc.top += delta; rc.bottom -= delta;
DrawFocusRect(hDC, &rc);
}
SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hFramePen);
DeleteObject((HANDLE)hShadowBrush);
DeleteObject((HANDLE)hBackgrndBrush);
DeleteObject((HANDLE)rgn1);
DeleteObject((HANDLE)rgn2);
DeleteObject((HANDLE)rgn);
}
static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
{
HPEN hOldPen, hShadowPen, hFramePen;
HBRUSH hOldBrush, hBackgrndBrush;
HRGN rgn1, rgn2, rgn;
int len;
static char text[50+1];
DWORD dwTextSize;
int delta;
TEXTMETRIC tm;
hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
hBackgrndBrush = CreateSolidBrush(color_btnface);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
SetBkMode(hDC, TRANSPARENT);
/* give parent a chance to alter parameters: */
SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hButton, CTLCOLOR_BTN));
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
/* draw button shadow: */
hShadowPen = CreatePen(PS_SOLID, 1, color_btnshadow);
SelectObject(hDC, (HANDLE)hShadowPen);
MoveTo(hDC, rc.left+1, rc.bottom-1);
LineTo(hDC, rc.left+1, rc.top+1);
LineTo(hDC, rc.right-1, rc.top+1);
/* draw button label, if any: */
len = GetWindowText(hButton, text, sizeof text);
if (len >= 1) {
rc.top++; rc.left++;
DrawText(hDC, text, len, &rc,
DT_SINGLELINE | DT_CENTER| DT_VCENTER);
}
/* do we have the focus? */
if (len >= 1 && GetFocus() == hButton) {
dwTextSize = GetTextExtent(hDC, text, len);
delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
rc.left += delta; rc.right -= delta;
GetTextMetrics(hDC, &tm);
delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
rc.top += delta; rc.bottom -= delta;
DrawFocusRect(hDC, &rc);
}
SelectObject(hDC, (HANDLE)hOldPen);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hBackgrndBrush);
DeleteObject(SelectObject(hDC, (HANDLE)hFramePen));
DeleteObject(SelectObject(hDC, (HANDLE)hShadowPen));
}
/**********************************************************************
* Check Box Functions
*/
static LONG CB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc, rc3;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush, hGrayBrush;
int textlen, delta;
char *text;
HANDLE hText;
TEXTMETRIC tm;
SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Rectangle(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
if (pressed)
Rectangle(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
tm.tmHeight + delta - 1);
switch ((WORD)(*(wndPtr->wExtra)))
{
case 1:
MoveTo(hDC, 0, rc.top + delta);
LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1);
MoveTo(hDC, 0, tm.tmHeight + delta - 1);
LineTo(hDC, tm.tmHeight - 1, rc.top + delta);
break;
case 2:
rc3.left = 1;
rc3.top = rc.top + delta + 1;
rc3.right = tm.tmHeight - 1;
rc3.bottom = tm.tmHeight + delta - 1;
FillRect(hDC, &rc3, hGrayBrush);
break;
}
rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */
if (GetFocus() == hWnd)
{
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top += delta - 1;
rc.bottom -= delta + 1;
rc.left--;
rc.right = rc.left + size.cx + 2;
DrawFocusRect(hDC, &rc);
}
USER_HEAP_FREE(hText);
GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style;
pressed = FALSE;
ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
style = wndPtr->dwStyle & 0x0000000F;
if (style == BS_AUTOCHECKBOX)
{
switch ((WORD)(*(wndPtr->wExtra)))
{
case 0:
(WORD)(*(wndPtr->wExtra)) = 1;
break;
case 1:
(WORD)(*(wndPtr->wExtra)) = 0;
break;
}
}
else if (style == BS_AUTO3STATE)
{
switch ((WORD)(*(wndPtr->wExtra)))
{
case 0:
(WORD)(*(wndPtr->wExtra)) = 1;
break;
case 1:
(WORD)(*(wndPtr->wExtra)) = 2;
break;
case 2:
(WORD)(*(wndPtr->wExtra)) = 0;
break;
}
}
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
}
static LONG CB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG CB_SetCheck(HWND hWnd, WORD wParam)
{
WND *wndPtr = WIN_FindWndPtr(hWnd);
if ((WORD)(*(wndPtr->wExtra)) != wParam)
{
(WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
GlobalUnlock(hWnd);
}
static LONG CB_GetCheck(HWND hWnd)
{
WORD wResult;
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
GlobalUnlock(hWnd);
return (LONG)wResult;
}
/**********************************************************************
* Radio Button Functions
*/
static LONG RB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush, hOldBrush;
int textlen, delta;
char *text;
HANDLE hText;
TEXTMETRIC tm;
SIZE size;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextMetrics(hDC, &tm);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
if (pressed)
Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
tm.tmHeight + delta - 1);
if ((WORD)(*(wndPtr->wExtra)) == 1)
{
hBrush = CreateSolidBrush(color_windowtext);
hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush);
Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3,
tm.tmHeight + delta -3);
SelectObject(hDC, (HANDLE)hOldBrush);
DeleteObject((HANDLE)hBrush);
}
rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
/* do we have the focus? */
if (GetFocus() == hWnd)
{
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top += delta - 1;
rc.bottom -= delta + 1;
rc.left--;
rc.right = rc.left + size.cx + 2;
DrawFocusRect(hDC, &rc);
}
USER_HEAP_FREE(hText);
GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
/* SetFocus(hWnd); */
SetCapture(hWnd);
pressed = TRUE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
}
static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
WND *wndPtr = WIN_FindWndPtr(hWnd);
LONG style;
pressed = FALSE;
ReleaseCapture();
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
style = wndPtr->dwStyle & 0x0000000F;
if (style == BS_AUTORADIOBUTTON)
(WORD)(*(wndPtr->wExtra)) = 1;
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
HDC hDC;
TEXTMETRIC tm;
int delta;
hDC = GetDC(hWnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hWnd, hDC);
GetClientRect(hWnd, &rc);
delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
rc.top += delta;
rc.bottom = tm.tmHeight + delta;
rc.right = tm.tmHeight;
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
}
static LONG RB_KillFocus(HWND hWnd)
{
pressed = FALSE;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG RB_SetCheck(HWND hWnd, WORD wParam)
{
WND *wndPtr = WIN_FindWndPtr(hWnd);
if ((WORD)(*(wndPtr->wExtra)) != wParam)
{
(WORD)(*(wndPtr->wExtra)) = wParam;
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
GlobalUnlock(hWnd);
}
static LONG RB_GetCheck(HWND hWnd)
{
WORD wResult;
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
GlobalUnlock(hWnd);
return (LONG)wResult;
}
/**********************************************************************
* Group Box Functions
*/
static LONG GB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
RECT rc;
HDC hDC;
HPEN hPen, hOldPen;
HBRUSH hBrush;
int textlen;
char *text;
HANDLE hText;
SIZE size;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hPen = CreatePen(PS_SOLID, 1, color_windowtext);
hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
textlen = GetWindowTextLength(hWnd);
hText = USER_HEAP_ALLOC(0, textlen+1);
text = USER_HEAP_ADDR(hText);
GetWindowText(hWnd, text, textlen+1);
GetTextExtentPoint(hDC, text, textlen, &size);
rc.top = 5;
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
rc.left = 10;
rc.top = 0;
rc.right = rc.left + size.cx + 1;
rc.bottom = size.cy;
DrawText(hDC, text, textlen, &rc, DT_SINGLELINE);
USER_HEAP_FREE(hText);
EndPaint(hWnd, &ps);
}
/**********************************************************************
* User Button Functions
*/
static LONG UB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
RECT rc;
HBRUSH hBrush;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
MAKELPARAM(hWnd, CTLCOLOR_BTN));
FillRect(hDC, &rc, hBrush);
NOTIFY_PARENT(hWnd, BN_PAINT);
/* do we have the focus? */
if (GetFocus() == hWnd)
DrawFocusRect(hDC, &rc);
EndPaint(hWnd, &ps);
}
static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
/* SetFocus(hWnd); */
SetCapture(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_HILITE);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
RECT rc;
ReleaseCapture();
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
{
NOTIFY_PARENT(hWnd, BN_CLICKED);
NOTIFY_PARENT(hWnd, BN_UNHILITE);
}
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
static LONG UB_KillFocus(HWND hWnd)
{
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
/**********************************************************************
* Ownerdrawn Button Functions
*/
static LONG OB_Paint(HWND hWnd)
{
PAINTSTRUCT ps;
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_DRAWENTIRE;
/* printf("ownerdrawn button WM_DRAWITEM CtrlID=%X\n", lpdis->CtlID);*/
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
EndPaint(hWnd, &ps);
}
static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
{
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
/* SetFocus(hWnd); */
SetCapture(hWnd);
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_SELECT;
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC);
}
static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
{
HDC hDC;
RECT rc;
HANDLE hDis;
LPDRAWITEMSTRUCT lpdis;
WND *wndPtr = WIN_FindWndPtr(hWnd);
ReleaseCapture();
hDC = GetDC(hWnd);
GetClientRect(hWnd, &rc);
if (PtInRect(&rc, MAKEPOINT(lParam)))
NOTIFY_PARENT(hWnd, BN_CLICKED);
GetClientRect(hWnd, &rc);
hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
lpdis->hDC = hDC;
lpdis->itemID = 0;
CopyRect(&lpdis->rcItem, &rc);
lpdis->CtlID = wndPtr->wIDmenu;
lpdis->CtlType = ODT_BUTTON;
lpdis->itemAction = ODA_SELECT;
SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
USER_HEAP_FREE(hDis);
ReleaseDC(hWnd, hDC);
}
static LONG OB_KillFocus(HWND hWnd)
{
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}