diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/mxtk/mx.cpp | |
| download | archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.tar.xz archived-source-engine-2018-hl2-src-3bf9df6b2785fa6d951086978a3e66f49427166a.zip | |
Diffstat (limited to 'utils/mxtk/mx.cpp')
| -rw-r--r-- | utils/mxtk/mx.cpp | 1152 |
1 files changed, 1152 insertions, 0 deletions
diff --git a/utils/mxtk/mx.cpp b/utils/mxtk/mx.cpp new file mode 100644 index 0000000..8d5e35a --- /dev/null +++ b/utils/mxtk/mx.cpp @@ -0,0 +1,1152 @@ +// +// mxToolKit (c) 1999 by Mete Ciragan +// +// file: mx.cpp +// implementation: Win32 API +// last modified: Apr 18 1999, Mete Ciragan +// copyright: The programs and associated files contained in this +// distribution were developed by Mete Ciragan. The programs +// are not in the public domain, but they are freely +// distributable without licensing fees. These programs are +// provided without guarantee or warrantee expressed or +// implied. +// +#include "mxtk/mx.h" +#include "mxtk/mxWindow.h" +#include "mxtk/mxEvent.h" +#include "mxtk/mxLinkedList.h" +#include <windows.h> +#include <commctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "tier1/utlvector.h" + + +#define WM_MOUSEWHEEL 0x020A + +//#include <ostream.h" + + + +void mxTab_resizeChild (HWND hwnd); + + + +mxWindow *g_mainWindow = 0; +static mxLinkedList *g_widgetList = 0; +static mxWindow *g_idleWindow = 0; + +static MSG msg; +static HWND g_hwndToolTipControl = 0; +static bool isClosing = false; +static HACCEL g_hAcceleratorTable = NULL; + +void mx::createAccleratorTable( int numentries, Accel_t *entries ) +{ + CUtlVector< ACCEL > accelentries; + + for ( int i = 0; i < numentries; ++i ) + { + const Accel_t& entry = entries[ i ]; + + ACCEL add; + add.key = entry.key; + add.cmd = entry.command; + add.fVirt = 0; + if ( entry.flags & ACCEL_ALT ) + { + add.fVirt |= FALT; + } + if ( entry.flags & ACCEL_CONTROL ) + { + add.fVirt |= FCONTROL; + } + if ( entry.flags & ACCEL_SHIFT ) + { + add.fVirt |= FSHIFT; + } + if ( entry.flags & ACCEL_VIRTKEY ) + { + add.fVirt |= FVIRTKEY; + } + + accelentries.AddToTail( add ); + } + + g_hAcceleratorTable = ::CreateAcceleratorTable( accelentries.Base(), accelentries.Count() ); +} + + + +void +mx_addWidget (mxWidget *widget) +{ + if (g_widgetList) + g_widgetList->add ((void *) widget); +} + + + +void +mx_removeWidget (mxWidget *widget) +{ + if (g_widgetList) + g_widgetList->remove ((void *) widget); +} + + + +HWND +mx_CreateToolTipControl () +{ + if (!g_hwndToolTipControl) + { + if (g_mainWindow) + { + g_hwndToolTipControl = CreateWindowEx (0, TOOLTIPS_CLASS, "", WS_POPUP | WS_EX_TOPMOST, + 0, 0, 0, 0, (HWND) g_mainWindow->getHandle (), + (HMENU) NULL, (HINSTANCE) GetModuleHandle (NULL), NULL); + } + } + + return g_hwndToolTipControl; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *window - +// *event - +// Output : static void +//----------------------------------------------------------------------------- +static void RecursiveHandleEvent( mxWindow *window, mxEvent *event ) +{ + while ( window ) + { + if ( window->handleEvent ( event ) ) + break; + + window = window->getParent(); + } +} + +char const *translatecode( int code ) +{ + switch ( code ) + { + case NM_CLICK: + return "NM_CLICK"; + case NM_CUSTOMDRAW: + return "NM_CUSTOMDRAW"; + case NM_DBLCLK: + return "NM_DBLCLK"; + case NM_KILLFOCUS: + return "NM_KILLFOCUS"; + case NM_RCLICK: + return "NM_RCLICK"; + case NM_RETURN: + return "NM_RETURN"; + case NM_SETCURSOR: + return "NM_SETCURSOR"; + case NM_SETFOCUS: + return "NM_SETFOCUS"; + case TVN_BEGINDRAG: + return "TVN_BEGINDRAG"; + case TVN_BEGINLABELEDIT: + return "TVN_BEGINLABELEDIT"; + case TVN_BEGINRDRAG: + return "TVN_BEGINRDRAG"; + case TVN_DELETEITEM: + return "TVN_DELETEITEM"; + case TVN_ENDLABELEDIT: + return "TVN_ENDLABELEDIT"; + case TVN_GETDISPINFO: + return "TVN_GETDISPINFO"; + case TVN_GETINFOTIP: + return "TVN_GETINFOTIP"; + case TVN_ITEMEXPANDED: + return "TVN_ITEMEXPANDED"; + case TVN_ITEMEXPANDING: + return "TVN_ITEMEXPANDING"; + case TVN_KEYDOWN : + return "TVN_KEYDOWN"; + case TVN_SELCHANGED : + return "TVN_SELCHANGED"; + case TVN_SELCHANGING : + return "TVN_SELCHANGING"; + case TVN_SETDISPINFO : + return "TVN_SETDISPINFO"; + case TVN_SINGLEEXPAND: + return "TVN_SINGLEEXPAND"; + } + + return "Unknown!!!"; +} +static LRESULT CALLBACK WndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam) +{ + static bool bDragging = FALSE; + + switch (uMessage) + { + case WM_SETFOCUS: + case WM_KILLFOCUS: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if ( window ) + { + mxEvent event; + event.event = mxEvent::Focus; + event.widget = NULL; + event.action = (uMessage == WM_SETFOCUS); + RecursiveHandleEvent( window, &event ); + return 0; + } + } + break; + + case WM_ACTIVATE: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if ( window ) + { + mxEvent event; + event.event = mxEvent::Activate; + event.widget = NULL; + event.action = (LOWORD( wParam ) != WA_INACTIVE); + RecursiveHandleEvent( window, &event ); + return 0; + } + } + break; + + case WM_COMMAND: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (LOWORD (wParam) > 0 && window) + { + WORD wNotifyCode = (WORD) HIWORD (wParam); + HWND hwndCtrl = (HWND) lParam; + mxEvent event; + + CHAR className[128]; + GetClassName (hwndCtrl, className, 128); + if (!strcmpi (className, "edit")) + { + if (wNotifyCode != EN_CHANGE) + break; + } + else if (!strcmpi (className, "combobox")) + { + if (wNotifyCode != CBN_SELCHANGE) + break; + } + else if (!strcmpi (className, "listbox")) + { + if (wNotifyCode != LBN_SELCHANGE) + break; + } + + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong ((HWND) lParam, GWL_USERDATA); + event.action = (int) LOWORD (wParam); + RecursiveHandleEvent( window, &event ); + } + } + break; + + case WM_NOTIFY: + { + if (isClosing) + break; + + NMHDR *nmhdr = (NMHDR *) lParam; + mxEvent event; + +#if 0 + //if ( nmhdr->idFrom > 0 ) + { + mxWidget *temp = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + if ( temp && temp->getType() == MX_TREEVIEW ) + { + NMTREEVIEW *nmt = ( NMTREEVIEW * )nmhdr; + + HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom); + + char sz[ 256 ]; + sprintf( sz, "tree view receiving notify %i : %s action %i old %p new %p selection %p\n", nmhdr->code, translatecode( nmhdr->code ), + nmt->action, nmt->itemOld, nmt->itemNew, hItem ); + + OutputDebugString( sz ); + } + } +#endif + + if (nmhdr->code == TVN_SELCHANGED) + { + if (nmhdr->idFrom > 0) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + event.action = (int) nmhdr->idFrom; + + RECT rc; + HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom); + TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE); + event.x = (int) rc.left; + event.y = (int) rc.bottom; + RecursiveHandleEvent( window, &event ); + + } + } + else if (nmhdr->code == LVN_ITEMCHANGED) + { + if (nmhdr->idFrom > 0) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + event.action = (int) nmhdr->idFrom; + + RecursiveHandleEvent( window, &event ); + } + } + else if (nmhdr->code == NM_RCLICK) + { + if (nmhdr->idFrom > 0) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + event.action = (int) nmhdr->idFrom; + event.flags = mxEvent::RightClicked; + + if ( event.widget ) + { + if ( event.widget->getType () == MX_TREEVIEW ) + { + RECT rc; + HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom); + TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE); + event.x = (int) rc.left; + event.y = (int) rc.bottom; + } + } + RecursiveHandleEvent( window, &event ); + } + } + else if (nmhdr->code == NM_DBLCLK) + { + if (nmhdr->idFrom > 0) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + event.action = (int) nmhdr->idFrom; + event.flags = mxEvent::DoubleClicked; + + if (event.widget ) + { + if ( event.widget->getType () == MX_TREEVIEW ) + { + RECT rc; + HTREEITEM hItem = TreeView_GetSelection (nmhdr->hwndFrom); + TreeView_GetItemRect (nmhdr->hwndFrom, hItem, &rc, TRUE); + event.x = (int) rc.left; + event.y = (int) rc.bottom; + } + } + + RecursiveHandleEvent( window, &event ); + return TRUE; + } + } + else if (nmhdr->code == TCN_SELCHANGING) + { + TC_ITEM ti; + + int index = TabCtrl_GetCurSel (nmhdr->hwndFrom); + if (index >= 0) + { + ti.mask = TCIF_PARAM; + TabCtrl_GetItem (nmhdr->hwndFrom, index, &ti); + mxWindow *window = (mxWindow *) ti.lParam; + if (window) + window->setVisible (false); + } + } + else if (nmhdr->code == TCN_SELCHANGE) + { + mxTab_resizeChild (nmhdr->hwndFrom); + if (nmhdr->idFrom > 0) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + event.event = mxEvent::Action; + event.widget = (mxWidget *) GetWindowLong (nmhdr->hwndFrom, GWL_USERDATA); + event.action = (int) nmhdr->idFrom; + RecursiveHandleEvent( window, &event ); + } + } + } + break; + + case WM_SIZE: + { + mxEvent event; + + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + event.event = mxEvent::Size; + event.width = (int) LOWORD (lParam); + event.height = (int) HIWORD (lParam); + window->handleEvent (&event); + } + } + break; + case WM_WINDOWPOSCHANGED: + { + mxEvent event; + + + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + event.event = mxEvent::PosChanged; + + WINDOWPOS *wp = ( WINDOWPOS * )lParam; + + event.x = wp->x; + event.y = wp->y; + event.width = wp->cx; + event.height = wp->cy; + + window->handleEvent (&event); + } + } + break; + + case WM_ERASEBKGND: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + if (window->getType () == MX_GLWINDOW) + return 0; + if (window->getType () == MX_MATSYSWINDOW) + return 0; + + if ( !isClosing && !window->PaintBackground() ) + { + return 0; + } + } + } + break; + + case WM_HSCROLL: + case WM_VSCROLL: + { + mxWidget *widget = (mxWidget *) GetWindowLong ((HWND) lParam, GWL_USERDATA); + if (!widget) + { + break; + } + + if (widget->getType() != MX_SCROLLBAR && widget->getType() != MX_SLIDER) + { + break; + } + + + switch (LOWORD (wParam)) + { + case TB_LINEUP: // SB_LINEUP SB_LINELEFT + break; + case TB_LINEDOWN: // SB_LINEDOWN SB_LINERIGHT + break; + case TB_PAGEUP: // SB_PAGEUP SB_PAGELEFT + break; + case TB_PAGEDOWN: // SB_PAGEDOWN SB_PAGERIGHT + break; + case TB_THUMBPOSITION: // SB_THUMBPOSITION + break; + case TB_THUMBTRACK: // SB_THUMBTRACK + break; + case TB_TOP: // SB_TOP SB_LEFT + break; + case TB_BOTTOM: // SB_BOTTOM SB_RIGHT + break; + case TB_ENDTRACK: // SB_ENDSCROLL + break; + default: + break; + } + + switch (LOWORD (wParam)) + { + case TB_LINEUP: // SB_LINEUP SB_LINELEFT + case TB_LINEDOWN: // SB_LINEDOWN SB_LINERIGHT + case TB_PAGEUP: // SB_PAGEUP SB_PAGELEFT + case TB_PAGEDOWN: // SB_PAGEDOWN SB_PAGERIGHT + case TB_THUMBPOSITION: // SB_THUMBPOSITION + case TB_THUMBTRACK: // SB_THUMBTRACK + case TB_TOP: // SB_TOP SB_LEFT + case TB_BOTTOM: // SB_BOTTOM SB_RIGHT + case TB_ENDTRACK: // SB_ENDSCROLL + { + mxEvent event; + + event.event = mxEvent::Action; + event.widget = widget; + event.action = widget->getId (); + event.modifiers = LOWORD (wParam); + event.height = HIWORD( wParam ); + mxWindow *window = widget->getParent (); + + if ( event.action > 0 ) + { + RecursiveHandleEvent( window, &event ); + } + } + break; + } + } + break; + + case WM_PAINT: + { + if ( !isClosing ) + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + window->redraw (); + } + } + } + break; + + case WM_PARENTNOTIFY: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + if ( wParam == WM_LBUTTONDOWN || + wParam == WM_MBUTTONDOWN || + wParam == WM_RBUTTONDOWN /*|| + wParam & WM_XBUTTONDOWN*/ ) + { + mxEvent event; + event.event = mxEvent::ParentNotify; + event.x = (short)LOWORD (lParam); + event.y = (short)HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if ( wParam == WM_LBUTTONDOWN ) + event.buttons |= mxEvent::MouseLeftButton; + + if ( wParam == WM_RBUTTONDOWN ) + event.buttons |= mxEvent::MouseRightButton; + + if ( wParam == WM_MBUTTONDOWN ) + event.buttons |= mxEvent::MouseMiddleButton; + + window->handleEvent (&event); + RecursiveHandleEvent( window, &event ); + return 0; + } + } + } + break; + + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + { + bDragging = TRUE; + SetCapture (hwnd); + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + + if (window) + { + mxEvent event; + event.event = mxEvent::MouseDown; + event.x = (short)LOWORD (lParam); + event.y = (short)HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if (uMessage == WM_MBUTTONDOWN) + event.buttons |= mxEvent::MouseMiddleButton; + else if (uMessage == WM_RBUTTONDOWN) + event.buttons |= mxEvent::MouseRightButton; + else + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_LBUTTON) + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_RBUTTON) + event.buttons |= mxEvent::MouseRightButton; + + if (wParam & MK_MBUTTON) + event.buttons |= mxEvent::MouseMiddleButton; + + if (wParam & MK_CONTROL) + event.modifiers |= mxEvent::KeyCtrl; + + if (wParam & MK_SHIFT) + event.modifiers |= mxEvent::KeyShift; + + window->handleEvent (&event); + } + } + break; + + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::MouseUp; + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if (uMessage == WM_MBUTTONUP) + event.buttons |= mxEvent::MouseMiddleButton; + else if (uMessage == WM_RBUTTONUP) + event.buttons |= mxEvent::MouseRightButton; + else + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_LBUTTON) + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_RBUTTON) + event.buttons |= mxEvent::MouseRightButton; + + if (wParam & MK_MBUTTON) + event.buttons |= mxEvent::MouseMiddleButton; + + if (wParam & MK_CONTROL) + event.modifiers |= mxEvent::KeyCtrl; + + if (wParam & MK_SHIFT) + event.modifiers |= mxEvent::KeyShift; + + window->handleEvent (&event); + } + bDragging = FALSE; + ReleaseCapture (); + } + break; + + case WM_MOUSEMOVE: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + + if (bDragging) + event.event = mxEvent::MouseDrag; + else + event.event = mxEvent::MouseMove; + + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if (wParam & MK_LBUTTON) + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_RBUTTON) + event.buttons |= mxEvent::MouseRightButton; + + if (wParam & MK_MBUTTON) + event.buttons |= mxEvent::MouseMiddleButton; + + if (wParam & MK_CONTROL) + event.modifiers |= mxEvent::KeyCtrl; + + if (wParam & MK_SHIFT) + event.modifiers |= mxEvent::KeyShift; + + window->handleEvent (&event); + } + } + break; + case WM_NCLBUTTONDOWN: + case WM_NCMBUTTONDOWN: + case WM_NCRBUTTONDOWN: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + + if (window) + { + mxEvent event; + event.event = mxEvent::NCMouseDown; + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if (uMessage == WM_NCMBUTTONDOWN) + event.buttons |= mxEvent::MouseMiddleButton; + else if (uMessage == WM_NCRBUTTONDOWN) + event.buttons |= mxEvent::MouseRightButton; + else + event.buttons |= mxEvent::MouseLeftButton; + + window->handleEvent (&event); + } + } + break; + + case WM_NCLBUTTONUP: + case WM_NCMBUTTONUP: + case WM_NCRBUTTONUP: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::NCMouseUp; + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + if (uMessage == WM_NCMBUTTONUP) + event.buttons |= mxEvent::MouseMiddleButton; + else if (uMessage == WM_NCRBUTTONUP) + event.buttons |= mxEvent::MouseRightButton; + else + event.buttons |= mxEvent::MouseLeftButton; + + window->handleEvent (&event); + } + } + break; + + case WM_NCMOUSEMOVE: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + + event.event = mxEvent::NCMouseMove; + + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + event.buttons = 0; + event.modifiers = 0; + + window->handleEvent (&event); + } + } + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::KeyDown; + event.key = (int) wParam; + if ( window->handleEvent (&event) ) + return 0; + } + } + break; + + case WM_CHAR: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::Char; + event.key = (int) wParam; + if ( window->handleEvent (&event) ) + return 0; + } + } + break; + + case WM_SYSCHAR: + return 0; + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::KeyUp; + event.key = (int) wParam; + if ( window->handleEvent (&event) ) + return 0; + } + } + break; + + case WM_MOUSEWHEEL: + { + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + memset( &event, 0, sizeof( event ) ); + event.event = mxEvent::MouseWheeled; + event.x = (short) LOWORD (lParam); + event.y = (short) HIWORD (lParam); + + if (wParam & MK_LBUTTON) + event.buttons |= mxEvent::MouseLeftButton; + + if (wParam & MK_RBUTTON) + event.buttons |= mxEvent::MouseRightButton; + + if (wParam & MK_MBUTTON) + event.buttons |= mxEvent::MouseMiddleButton; + + if (wParam & MK_CONTROL) + event.modifiers |= mxEvent::KeyCtrl; + + if (wParam & MK_SHIFT) + event.modifiers |= mxEvent::KeyShift; + + event.height = (short)HIWORD( wParam );; + RecursiveHandleEvent( window, &event ); + } + } + break; + case WM_TIMER: + { + if (isClosing) + break; + + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::Timer; + window->handleEvent (&event); + } + } + break; + + case WM_CLOSE: + if (g_mainWindow) + { + if ((void *) hwnd == g_mainWindow->getHandle ()) + { + mx::quit (); + } + else + { + ShowWindow (hwnd, SW_HIDE); + + mxWindow *window = (mxWindow *) GetWindowLong (hwnd, GWL_USERDATA); + if (window) + { + mxEvent event; + event.event = mxEvent::Close; + window->handleEvent( &event ); + } + } + } + //else // shouldn't happen + //DestroyWindow (hwnd); + return 0; +/* + case WM_DESTROY: + if (g_mainWindow) + { + if ((void *) hwnd == g_mainWindow->getHandle ()) + mx::quit (); + } + break; +*/ + } + + return DefWindowProc (hwnd, uMessage, wParam, lParam); +} + + + +int +mx::init(int argc, char **argv) +{ + WNDCLASS wc; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = (HINSTANCE) GetModuleHandle (NULL); + wc.hIcon = LoadIcon (wc.hInstance, "MX_ICON"); + wc.hCursor = LoadCursor (NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH) COLOR_WINDOW; + wc.lpszMenuName = NULL; + wc.lpszClassName = "mx_class"; + + if (!wc.hIcon) + wc.hIcon = LoadIcon (NULL, IDI_WINLOGO); + + if (!RegisterClass (&wc)) + return 0; + + InitCommonControls (); + + g_widgetList = new mxLinkedList (); + + isClosing = false; + + return 1; +} + + + +int +mx::run() +{ + int messagecount = 0; + + while (1) + { + bool doframe = false; + if ( PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE) || !g_idleWindow ) + { + if (!GetMessage (&msg, NULL, 0, 0)) + { + doframe = false; + break; + } + + if ( !g_hAcceleratorTable || + !TranslateAccelerator( (HWND)g_mainWindow->getHandle (), g_hAcceleratorTable, &msg )) + { + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + messagecount++; + + if ( messagecount > 10 ) + { + messagecount = 0; + doframe = true; + } + } + else if (g_idleWindow) + { + doframe = true; + messagecount = 0; + } + + if ( doframe && g_idleWindow ) + { + mxEvent event; + event.event = mxEvent::Idle; + g_idleWindow->handleEvent (&event); + } + } + + return msg.wParam; +} + + + +int +mx::check () +{ + if (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if (GetMessage (&msg, NULL, 0, 0)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + return 1; + } + + return 0; +} + + + +void +mx::quit () +{ + isClosing = true; + + mxWindow *mainwnd = getMainWindow(); + if ( mainwnd ) + { + if ( !mainwnd->Closing() ) + { + isClosing = false; + return; + } + } + + if (g_widgetList) + { + // remove from back to front + mxListNode *node = g_widgetList->getLast (); + + // Pass 1, see if anyone objects to closing + while (node) + { + mxWidget *widget = (mxWidget *) g_widgetList->getData (node); + node = g_widgetList->getPrev (node); + + bool canclose = true; + if ( widget ) + { + if ( !widget->CanClose() ) + { + canclose = false; + } + } + + if ( !canclose ) + { + isClosing = false; + return; + } + } + + node = g_widgetList->getLast (); + + // Pass 2, call OnDelete to allow final cleanup + while (node) + { + mxWidget *widget = (mxWidget *) g_widgetList->getData (node); + node = g_widgetList->getPrev (node); + + if ( widget ) + { + widget->OnDelete(); + } + } + + node = g_widgetList->getLast (); + + // Pass 3, delete stuff + while (node) + { + mxWidget *widget = (mxWidget *) g_widgetList->getData (node); + node = g_widgetList->getPrev (node); + + // remove it! + if ( widget ) + { + delete widget; + } + } + + delete g_widgetList; + } + + if (g_hwndToolTipControl) + DestroyWindow (g_hwndToolTipControl); + + if ( g_hAcceleratorTable ) + { + DestroyAcceleratorTable( g_hAcceleratorTable ); + g_hAcceleratorTable = 0; + } + + PostQuitMessage (0); + UnregisterClass ("mx_class", (HINSTANCE) GetModuleHandle (NULL)); +} + + + +int +mx::setDisplayMode (int w, int h, int bpp) +{ + DEVMODE dm; + + dm.dmSize = sizeof (DEVMODE); + dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + dm.dmBitsPerPel = bpp; + dm.dmPelsWidth = w; + dm.dmPelsHeight = h; + + if (w == 0 || h == 0 || bpp == 0) + ChangeDisplaySettings (0, 0); + else + ChangeDisplaySettings (&dm, CDS_FULLSCREEN); + + return 0; +} + + + +void +mx::setIdleWindow (mxWindow *window) +{ + g_idleWindow = window; +} + + + +int +mx::getDisplayWidth () +{ + return (int) GetSystemMetrics (SM_CXSCREEN); +} + + + +int +mx::getDisplayHeight () +{ + return (int) GetSystemMetrics (SM_CYSCREEN); +} + + + +mxWindow* +mx::getMainWindow () +{ + return g_mainWindow; +} + + + +const char * +mx::getApplicationPath () +{ + static char path[256]; + GetModuleFileName (0, path, 256); + char *ptr = strrchr (path, '\\'); + if (ptr) + *ptr = '\0'; + + return path; +} + + + +int +mx::getTickCount () +{ + return (int) GetTickCount (); +} |