#include "GUI.h"
LRESULT
CommonMsgLoop(NOTXSPROC
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam, WNDPROC wndprocOriginal)
{
LPPERLWIN32GUI_USERDATA perlud;
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(CommonMsgLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
switch
(uMsg) {
case
WM_PAINT:
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) hwnd, GWLP_USERDATA);
if
(perlud && (perlud->dwPlStyle & PERLWIN32GUI_FLICKERFREE)) {
WINDOWINFO pwi;
RECT cr;
pwi.cbSize =
sizeof
(WINDOWINFO);
GetWindowInfo(hwnd,&pwi);
LONG
width = pwi.rcClient.right - pwi.rcClient.left;
LONG
height = pwi.rcClient.bottom - pwi.rcClient.top;
cr.left = 0;
cr.right = width;
cr.top = 0;
cr.bottom = height;
LONG
offsetx = pwi.rcClient.left - pwi.rcWindow.left;
LONG
offsety = pwi.rcClient.top - pwi.rcWindow.top;
HDC
hdc = GetDC(hwnd);
HDC
hdc2 = CreateCompatibleDC(hdc);
HBITMAP
hbmp = CreateCompatibleBitmap(hdc, width + offsetx, height + offsety);
HBITMAP
holdbmp = (
HBITMAP
) SelectObject(hdc2, hbmp);
HBRUSH
bgBrush = (
HBRUSH
) GetClassLongPtr (hwnd, GCLP_HBRBACKGROUND);
cr.right += offsetx;
cr.bottom += offsety;
FillRect(hdc2, &cr, bgBrush);
SendMessage(hwnd, WM_PRINT, (
WPARAM
) hdc2, PRF_CLIENT | PRF_NONCLIENT | PRF_CHILDREN);
BitBlt(hdc, 0, 0, width, height, hdc2, offsetx, offsety, SRCCOPY);
SelectObject(hdc2, holdbmp);
ValidateRect(hwnd, NULL);
DeleteObject(hbmp);
DeleteDC(hdc2);
ReleaseDC(hwnd, hdc);
return
(
LRESULT
) 0;
}
break
;
case
WM_ERASEBKGND:
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) hwnd, GWLP_USERDATA);
if
(perlud && (perlud->dwPlStyle & PERLWIN32GUI_FLICKERFREE)) {
return
(
LRESULT
) 1;
}
if
(perlud && perlud->hBackgroundBrush && (perlud->iClass == WIN32__GUI__WINDOW ||
perlud->iClass == WIN32__GUI__DIALOG ||
perlud->iClass == WIN32__GUI__SPLITTER) ) {
RECT rc;
GetClientRect(hwnd, &rc);
FillRect((
HDC
)wParam, &rc, perlud->hBackgroundBrush);
return
(
LRESULT
) 1;
}
break
;
case
WM_CTLCOLOREDIT:
case
WM_CTLCOLORSTATIC:
case
WM_CTLCOLORBTN:
case
WM_CTLCOLORLISTBOX:
{
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) lParam, GWLP_USERDATA);
if
( ValidUserData(perlud) ) {
if
(uMsg == WM_CTLCOLORSTATIC) {
if
(perlud->iClass == WIN32__GUI__EDIT)
SetBkColor((
HDC
) wParam, GetSysColor(COLOR_BTNFACE));
else
SetBkMode((
HDC
) wParam, TRANSPARENT);
}
if
(perlud->clrForeground != CLR_INVALID)
SetTextColor((
HDC
) wParam, perlud->clrForeground);
if
(perlud->clrBackground != CLR_INVALID) {
SetBkColor((
HDC
) wParam, perlud->clrBackground);
return
((
LRESULT
) perlud->hBackgroundBrush);
}
}
LONG_PTR
hbrBackground;
if
(hbrBackground = GetClassLongPtr((
HWND
)lParam, GCLP_HBRBACKGROUND))
return
((
LRESULT
) hbrBackground);
switch
(uMsg) {
case
WM_CTLCOLOREDIT:
case
WM_CTLCOLORLISTBOX:
return
((
LRESULT
) GetSysColorBrush(COLOR_WINDOW));
break
;
default
:
return
((
LRESULT
) GetSysColorBrush(COLOR_BTNFACE));
break
;
}
}
break
;
case
WM_GETMINMAXINFO:
{
LPMINMAXINFO minmax;
LPPERLWIN32GUI_USERDATA perlud;
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( ValidUserData(perlud) && !(perlud->dwPlStyle & PERLWIN32GUI_MDICHILD) ) {
minmax = (LPMINMAXINFO) lParam;
if
(perlud->iMinWidth != -1) minmax->ptMinTrackSize.x = (
LONG
) perlud->iMinWidth;
if
(perlud->iMaxWidth != -1) minmax->ptMaxTrackSize.x = (
LONG
) perlud->iMaxWidth;
if
(perlud->iMinHeight != -1) minmax->ptMinTrackSize.y = (
LONG
) perlud->iMinHeight;
if
(perlud->iMaxHeight != -1) minmax->ptMaxTrackSize.y = (
LONG
) perlud->iMaxHeight;
return
0;
}
}
break
;
case
WM_SETCURSOR:
{
WORD
nHitTest = LOWORD( lParam );
if
( nHitTest == HTCLIENT ) {
LPPERLWIN32GUI_USERDATA perlud;
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) wParam, GWLP_USERDATA);
if
( ValidUserData(perlud) && perlud->hCursor != NULL ) {
SetCursor( perlud->hCursor );
return
TRUE;
}
}
break
;
}
case
WM_NEXTDLGCTL:
{
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( ValidUserData(perlud) && (perlud->dwPlStyle & PERLWIN32GUI_DIALOGUI) ) {
if
(LOWORD(lParam))
SetFocus((
HWND
)wParam);
else
SetFocus(GetNextDlgTabItem(hwnd, GetFocus(), (
BOOL
)wParam));
return
0;
}
}
}
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(CommonMsgLoop) returning DefWindowProc\n"
);
#endif
if
(wndprocOriginal != NULL) {
return
CallWindowProc((WNDPROC_CAST) wndprocOriginal, hwnd, uMsg, wParam, lParam);
}
else
{
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
LRESULT
CALLBACK WindowMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
LPPERLWIN32GUI_USERDATA perlud;
LPPERLWIN32GUI_USERDATA childud;
int
PerlResult = 1;
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(WindowMsgLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
perlud = (LPPERLWIN32GUI_USERDATA) ((CREATESTRUCT *) lParam)->lpCreateParams;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
perlud->WndProc = (LWNDPROC_CAST) GetDefClassProc (NOTXSCALL ((CREATESTRUCT *) lParam)->lpszClass);
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
(!ValidUserData(perlud)) {
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud->forceResult = 0;
PERLUD_FETCH;
switch
(uMsg) {
case
WM_COMMAND:
if
(HIWORD(wParam) == 0 && lParam == 0) {
PerlResult = DoEvent_Menu(NOTXSCALL hwnd, LOWORD(wParam));
}
else
if
(HIWORD(wParam) == 1 && lParam == 0) {
PerlResult = DoEvent_Accelerator(NOTXSCALL perlud, LOWORD(wParam));
}
else
{
childud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) lParam, GWLP_USERDATA);
if
( ValidUserData(childud) ) {
childud->forceResult = 0;
PerlResult = OnEvent[childud->iClass](NOTXSCALL childud, uMsg, wParam, lParam);
if
(IsWindow((
HWND
)lParam) && childud->avHooks != NULL)
DoHook(NOTXSCALL childud, (
UINT
) HIWORD(wParam), wParam, lParam, &PerlResult, WM_COMMAND);
if
(IsWindow((
HWND
)lParam) && childud->forceResult != 0) {
perlud->forceResult = childud->forceResult;
childud->forceResult = 0;
}
}
}
break
;
case
WM_NOTIFY:
childud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(((LPNMHDR) lParam)->hwndFrom, GWLP_USERDATA);
if
( ValidUserData(childud) ) {
childud->forceResult = 0;
switch
(((LPNMHDR) lParam)->code) {
case
NM_CLICK:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_CLICK,
"Click"
, -1 );
break
;
case
NM_RCLICK:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_RIGHTCLICK,
"RightClick"
, -1 );
break
;
case
NM_DBLCLK:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_DBLCLICK,
"DblClick"
, -1 );
break
;
case
NM_RDBLCLK:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_DBLRIGHTCLICK,
"DblRightClick"
, -1 );
break
;
case
NM_SETFOCUS:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_GOTFOCUS,
"GotFocus"
, -1 );
break
;
case
NM_KILLFOCUS:
PerlResult = DoEvent(NOTXSCALL childud, PERLWIN32GUI_NEM_LOSTFOCUS,
"LostFocus"
, -1 );
break
;
default
:
PerlResult = OnEvent[childud->iClass](NOTXSCALL childud, uMsg, wParam, lParam);
break
;
}
if
(IsWindow(((LPNMHDR)lParam)->hwndFrom) && childud->avHooks != NULL)
DoHook(NOTXSCALL childud, (
UINT
) (((LPNMHDR) lParam)->code), wParam, lParam, &PerlResult, WM_NOTIFY);
if
(IsWindow(((LPNMHDR)lParam)->hwndFrom) && childud->forceResult != 0) {
perlud->forceResult = childud->forceResult;
childud->forceResult = 0;
}
}
break
;
case
WM_DESTROY:
if
(perlud->WndProc)
PerlResult = CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
else
PerlResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
PERLUD_FREE;
return
PerlResult;
case
WM_MOUSEMOVE:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEMOVE,
"MouseMove"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEDOWN,
"MouseDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEUP,
"MouseUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEDBLCLK,
"MouseDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEDOWN,
"MouseRightDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEUP,
"MouseRightUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEDBLCLK,
"MouseRightDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEDOWN,
"MouseMiddleDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEUP,
"MouseMiddleUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEDBLCLK,
"MouseMiddleDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_KEYDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_KEYDOWN,
"KeyDown"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_KEYUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_KEYUP,
"KeyUp"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_CHAR:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_CHAR,
"Char"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MOUSEHOVER :
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEOVER,
"MouseOver"
, -1);
if
(PerlResult) {
TRACKMOUSEEVENT tme;
tme.cbSize =
sizeof
(TRACKMOUSEEVENT);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_QUERY;
if
(_TrackMouseEvent( &tme )) {
_TrackMouseEvent( &tme );
}
}
break
;
case
WM_MOUSELEAVE :
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEOUT,
"MouseOut"
, -1);
if
(PerlResult) {
TRACKMOUSEEVENT tme;
tme.cbSize =
sizeof
(TRACKMOUSEEVENT);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_QUERY;
if
(_TrackMouseEvent( &tme )) {
_TrackMouseEvent( &tme );
}
}
break
;
case
WM_PAINT :
case
WM_ACTIVATE :
case
WM_SYSCOMMAND:
case
WM_SIZE:
case
WM_MDIACTIVATE:
case
WM_SETFOCUS:
case
WM_INITMENU:
PerlResult = OnEvent[perlud->iClass](NOTXSCALL perlud, uMsg, wParam, lParam);
break
;
case
WM_HSCROLL:
case
WM_VSCROLL:
childud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr((
HWND
) lParam, GWLP_USERDATA);
if
(ValidUserData(childud))
PerlResult = OnEvent[childud->iClass](NOTXSCALL childud, uMsg, wParam, lParam);
else
PerlResult = OnEvent[perlud->iClass](NOTXSCALL perlud, uMsg, wParam, lParam);
break
;
case
WM_TIMER:
PerlResult = DoEvent_Timer (NOTXSCALL perlud, (
int
) wParam, PERLWIN32GUI_NEM_TIMER,
"Timer"
, -1);
break
;
case
WM_NOTIFYICON:
switch
(lParam) {
case
WM_LBUTTONDOWN:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"Click"
, -1);
break
;
case
WM_LBUTTONDBLCLK:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"DblClick"
, -1);
break
;
case
WM_RBUTTONDOWN:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"RightClick"
, -1);
break
;
case
WM_RBUTTONDBLCLK:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"RightDblClick"
, -1);
break
;
case
WM_MBUTTONDOWN:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"MiddleClick"
, -1);
break
;
case
WM_MBUTTONDBLCLK:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"MiddleDblClick"
, -1);
break
;
default
:
PerlResult = DoEvent_NotifyIcon (NOTXSCALL perlud, (
int
) wParam,
"MouseEvent"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
-1);
break
;
}
break
;
case
WM_DROPFILES:
{ HV *dropfiles_stash = gv_stashpv(
"Win32::GUI::DropFiles"
, 0);
if
(dropfiles_stash) {
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_DROPFILE,
"DropFiles"
,
PERLWIN32GUI_ARGTYPE_SV, CreateObjectWithHandle(NOTXSCALL
"Win32::GUI::DropFiles"
, (
HWND
)wParam),
-1);
}
else
{
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_DROPFILE,
"DropFiles"
,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
DragFinish((
HDROP
)wParam);
}
}
break
;
}
if
(IsWindow(hwnd) && perlud->avHooks != NULL) {
DoHook(NOTXSCALL perlud, uMsg, wParam, lParam, &PerlResult,0);
}
if
(PerlResult == -1) {
if
(IsWindow(hwnd)) {
PostMessage(hwnd, WM_EXITLOOP, (
WPARAM
) -1, 0);
}
else
{
PostThreadMessage(GetCurrentThreadId(), WM_EXITLOOP, (
WPARAM
) -1, 0);
}
PerlResult = 0;
}
else
if
(IsWindow(hwnd) && PerlResult != 0) {
PerlResult = CommonMsgLoop(NOTXSCALL hwnd, uMsg, wParam, lParam, perlud->WndProc);
}
else
if
(IsWindow(hwnd) && perlud->forceResult != 0) {
return
perlud->forceResult;
}
return
PerlResult;
}
LRESULT
CALLBACK DefMDIFrameLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam) {
LPPERLWIN32GUI_USERDATA perlud;
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(DefMDIFrameLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( !ValidUserData(perlud)) {
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return
DefFrameProc(hwnd, INT2PTR(
HWND
, perlud->dwData), uMsg, wParam, lParam);
}
LRESULT
CALLBACK MDIFrameMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(MDIFrameMsgLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
LPPERLWIN32GUI_USERDATA perlud = (LPPERLWIN32GUI_USERDATA) ((CREATESTRUCT *) lParam)->lpCreateParams;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_MDIFRAME , 1);
perlud->WndProc = (LWNDPROC_CAST) DefMDIFrameLoop;
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return
CallWindowProc((WNDPROC_CAST) WindowMsgLoop, hwnd, uMsg, wParam, lParam);
}
LRESULT
CALLBACK MDIClientMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
LPPERLWIN32GUI_USERDATA perlud;
int
PerlResult = 1;
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(MDIClientMsgLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( !ValidUserData(perlud)) {
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
if
(perlud->WndProc)
PerlResult = CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
else
PerlResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
if
(uMsg == WM_DESTROY) {
PERLUD_FETCH;
PERLUD_FREE;
}
return
PerlResult;
}
LRESULT
CALLBACK DefMDIChildLoop (
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam) {
#ifdef PERLWIN32GUI_STRONGDEBUG
printf
(
"!XS(DefMDIChildLoop) got (0x%x, 0x%x, 0x%x, 0x%x)\n"
, hwnd, uMsg, wParam, lParam);
#endif
return
DefMDIChildProc(hwnd, uMsg, wParam, lParam);
}
LRESULT
CALLBACK MDIChildMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
LPMDICREATESTRUCT lpMdiCreate = (LPMDICREATESTRUCT) ((CREATESTRUCT *) lParam)->lpCreateParams;
LPPERLWIN32GUI_USERDATA perlud = (LPPERLWIN32GUI_USERDATA) lpMdiCreate->lParam;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_MDICHILD , 1);
perlud->WndProc = (LWNDPROC_CAST) DefMDIChildLoop;
perlud->dwData = PTR2IV(hwnd);
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return
CallWindowProc((WNDPROC_CAST) WindowMsgLoop, hwnd, uMsg, wParam, lParam);
}
LRESULT
CALLBACK ControlMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
LPPERLWIN32GUI_USERDATA perlud;
int
PerlResult = 1;
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
perlud = (LPPERLWIN32GUI_USERDATA) ((CREATESTRUCT *) lParam)->lpCreateParams;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
perlud->WndProc = (LWNDPROC_CAST) GetDefClassProc (NOTXSCALL ((CREATESTRUCT *) lParam)->lpszClass);
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( !ValidUserData(perlud)) {
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud->forceResult = 0;
PERLUD_FETCH;
switch
(uMsg) {
case
WM_DESTROY :
if
(perlud->WndProc)
PerlResult = CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
else
PerlResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
PERLUD_FREE;
return
PerlResult;
case
WM_TIMER:
PerlResult = DoEvent_Timer (NOTXSCALL perlud, wParam, PERLWIN32GUI_NEM_TIMER,
"Timer"
, -1);
break
;
case
WM_MOUSEMOVE:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEMOVE,
"MouseMove"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEDOWN,
"MouseDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEUP,
"MouseUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_LBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_LMOUSEDBLCLK,
"MouseDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEDOWN,
"MouseRightDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEUP,
"MouseRightUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_RBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_RMOUSEDBLCLK,
"MouseRightDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEDOWN,
"MouseMiddleDown"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEUP,
"MouseMiddleUp"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_MBUTTONDBLCLK:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MMOUSEDBLCLK,
"MouseMiddleDblClick"
,
PERLWIN32GUI_ARGTYPE_LONG, GET_X_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, GET_Y_LPARAM(lParam),
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_KEYDOWN:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_KEYDOWN,
"KeyDown"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_KEYUP:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_KEYUP,
"KeyUp"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_CHAR:
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_CHAR,
"Char"
,
PERLWIN32GUI_ARGTYPE_LONG, lParam,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
break
;
case
WM_COMMAND:
case
WM_NOTIFY :
if
(perlud->dwPlStyle & PERLWIN32GUI_CONTAINER) {
HWND
hwndParent = (
HWND
) GetWindowLongPtr(hwnd, GWLP_HWNDPARENT);
SendMessage(hwndParent, uMsg, wParam, lParam);
return
0;
}
case
WM_MOUSEHOVER :
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEOVER,
"MouseOver"
, -1);
if
(PerlResult) {
TRACKMOUSEEVENT tme;
tme.cbSize =
sizeof
(TRACKMOUSEEVENT);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_QUERY;
if
(_TrackMouseEvent( &tme )) {
_TrackMouseEvent( &tme );
}
}
break
;
case
WM_MOUSELEAVE :
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_MOUSEOUT,
"MouseOut"
, -1);
if
(PerlResult) {
TRACKMOUSEEVENT tme;
tme.cbSize =
sizeof
(TRACKMOUSEEVENT);
tme.hwndTrack = hwnd;
tme.dwFlags = TME_QUERY;
if
(_TrackMouseEvent( &tme )) {
_TrackMouseEvent( &tme );
}
}
break
;
case
WM_DROPFILES:
{ HV *dropfiles_stash = gv_stashpv(
"Win32::GUI::DropFiles"
, 0);
if
(dropfiles_stash) {
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_DROPFILE,
"DropFiles"
,
PERLWIN32GUI_ARGTYPE_SV, CreateObjectWithHandle(NOTXSCALL
"Win32::GUI::DropFiles"
, (
HWND
)wParam),
-1);
}
else
{
PerlResult = DoEvent(NOTXSCALL perlud, PERLWIN32GUI_NEM_DROPFILE,
"DropFiles"
,
PERLWIN32GUI_ARGTYPE_LONG, wParam,
-1);
DragFinish((
HDROP
)wParam);
}
}
}
if
(IsWindow(hwnd) && perlud->avHooks != NULL)
DoHook(NOTXSCALL perlud, uMsg,wParam,lParam,&PerlResult,0);
if
(IsWindow(hwnd) && PerlResult != 0) {
PerlResult = CommonMsgLoop(NOTXSCALL hwnd, uMsg, wParam, lParam, perlud->WndProc);
}
else
if
(IsWindow(hwnd) && perlud->forceResult != 0) {
return
perlud->forceResult;
}
return
PerlResult;
}
LRESULT
CALLBACK ContainerMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
LPPERLWIN32GUI_USERDATA perlud = (LPPERLWIN32GUI_USERDATA) ((CREATESTRUCT *) lParam)->lpCreateParams;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CONTAINER , 1);
perlud->WndProc = (LWNDPROC_CAST) GetDefClassProc (NOTXSCALL ((CREATESTRUCT *) lParam)->lpszClass);
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return
CallWindowProc((WNDPROC_CAST) ControlMsgLoop, hwnd, uMsg, wParam, lParam);
}
LRESULT
CALLBACK CustomMsgLoop(
HWND
hwnd,
UINT
uMsg,
WPARAM
wParam,
LPARAM
lParam)
{
LPPERLWIN32GUI_USERDATA perlud;
int
PerlResult = 1;
if
(uMsg == WM_CREATE || uMsg == WM_NCCREATE)
{
perlud = (LPPERLWIN32GUI_USERDATA) ((CREATESTRUCT *) lParam)->lpCreateParams;
if
(perlud != NULL) {
PERLUD_FETCH;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (
LONG_PTR
) perlud);
hv_store_mg(NOTXSCALL (HV*)SvRV(perlud->svSelf),
"-handle"
, 7, newSViv(PTR2IV(hwnd)), 0);
SwitchBit(perlud->dwPlStyle, PERLWIN32GUI_CUSTOMCLASS, 1);
perlud->WndProc = (LWNDPROC_CAST) GetDefClassProc (NOTXSCALL ((CREATESTRUCT *) lParam)->lpszClass);
if
(perlud->WndProc) {
return
CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
}
}
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud = (LPPERLWIN32GUI_USERDATA) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if
( !ValidUserData(perlud)) {
return
DefWindowProc(hwnd, uMsg, wParam, lParam);
}
perlud->forceResult = 0;
PERLUD_FETCH;
if
(uMsg == WM_DESTROY) {
if
(perlud->WndProc)
PerlResult = CallWindowProc((WNDPROC_CAST) perlud->WndProc, hwnd, uMsg, wParam, lParam);
else
PerlResult = DefWindowProc(hwnd, uMsg, wParam, lParam);
PERLUD_FREE;
return
PerlResult;
}
PerlResult = OnEvent[perlud->iClass](NOTXSCALL perlud, uMsg, wParam, lParam);
if
(IsWindow(hwnd) && perlud->avHooks != NULL && !(perlud->dwPlStyle & PERLWIN32GUI_INTERACTIVE))
DoHook(NOTXSCALL perlud, uMsg,wParam,lParam,&PerlResult,0);
if
(IsWindow(hwnd) && PerlResult != 0) {
if
(perlud->dwPlStyle & PERLWIN32GUI_INTERACTIVE)
PerlResult = CallWindowProc((WNDPROC_CAST) ControlMsgLoop, hwnd, uMsg, wParam, lParam);
else
PerlResult = CommonMsgLoop(NOTXSCALL hwnd, uMsg, wParam, lParam, perlud->WndProc);
}
else
if
(IsWindow(hwnd) && perlud->forceResult != 0) {
return
perlud->forceResult;
}
return
PerlResult;
}