📄 mx.cpp
字号:
//
// 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 <mx/mx.h>
#include <mx/mxWindow.h>
#include <mx/mxEvent.h>
#include <mx/mxLinkedList.h>
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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;
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_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_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 = (int) LOWORD (lParam);
event.y = (int) 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -