]> git.saurik.com Git - wxWidgets.git/blob - src/msw/window.cpp
Typos fixed.
[wxWidgets.git] / src / msw / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindow
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "window.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/setup.h"
25 #include "wx/menu.h"
26 #include "wx/dc.h"
27 #include "wx/dcclient.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
30 #include "wx/panel.h"
31 #include "wx/layout.h"
32 #include "wx/dialog.h"
33 #include "wx/frame.h"
34 #include "wx/listbox.h"
35 #include "wx/button.h"
36 #include "wx/msgdlg.h"
37
38 #include <stdio.h>
39 #endif
40
41 #if wxUSE_OWNER_DRAWN
42 #include "wx/ownerdrw.h"
43 #endif
44
45 #if wxUSE_DRAG_AND_DROP
46 #include "wx/msw/ole/droptgt.h"
47 #endif
48
49 #include "wx/menuitem.h"
50 #include "wx/log.h"
51
52 #if wxUSE_TOOLTIPS
53 #include "wx/tooltip.h"
54 #endif
55
56 #include "wx/intl.h"
57 #include "wx/log.h"
58
59 #include "wx/msw/private.h"
60
61 #include "wx/textctrl.h"
62
63 #include <string.h>
64
65 #ifndef __GNUWIN32__
66 #include <shellapi.h>
67 #include <mmsystem.h>
68 #endif
69
70 #ifdef __WIN32__
71 #include <windowsx.h>
72 #endif
73
74 #if ( defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__ )
75 #include <commctrl.h>
76 #endif
77
78 #ifndef __TWIN32__
79 #ifdef __GNUWIN32__
80 #include <wx/msw/gnuwin32/extra.h>
81 #endif
82 #endif
83
84 #ifdef GetCharWidth
85 #undef GetCharWidth
86 #endif
87
88 #ifdef FindWindow
89 #undef FindWindow
90 #endif
91
92 #ifdef GetClassName
93 #undef GetClassName
94 #endif
95
96 #ifdef GetClassInfo
97 #undef GetClassInfo
98 #endif
99
100 #ifdef __WXDEBUG__
101 const char *wxGetMessageName(int message);
102 #endif //__WXDEBUG__
103
104 #define WINDOW_MARGIN 3 // This defines sensitivity of Leave events
105
106 wxMenu *wxCurrentPopupMenu = NULL;
107 extern wxList WXDLLEXPORT wxPendingDelete;
108
109 void wxRemoveHandleAssociation(wxWindow *win);
110 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
111 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
112
113 #if !USE_SHARED_LIBRARY
114 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
115 #endif
116
117 BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
118 EVT_CHAR(wxWindow::OnChar)
119 EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
120 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
121 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
122 EVT_IDLE(wxWindow::OnIdle)
123 END_EVENT_TABLE()
124
125 // Find an item given the MS Windows id
126 wxWindow *wxWindow::FindItem(int id) const
127 {
128 // if ( !GetChildren() )
129 // return NULL;
130 wxNode *current = GetChildren().First();
131 while (current)
132 {
133 wxWindow *childWin = (wxWindow *)current->Data();
134
135 wxWindow *wnd = childWin->FindItem(id) ;
136 if ( wnd )
137 return wnd ;
138
139 if ( childWin->IsKindOf(CLASSINFO(wxControl)) )
140 {
141 wxControl *item = (wxControl *)childWin;
142 if ( item->GetId() == id )
143 return item;
144 else
145 {
146 // In case it's a 'virtual' control (e.g. radiobox)
147 if ( item->GetSubcontrols().Member((wxObject *)id) )
148 return item;
149 }
150 }
151 current = current->Next();
152 }
153 return NULL;
154 }
155
156 // Find an item given the MS Windows handle
157 wxWindow *wxWindow::FindItemByHWND(WXHWND hWnd, bool controlOnly) const
158 {
159 // if ( !GetChildren() )
160 // return NULL;
161 wxNode *current = GetChildren().First();
162 while (current)
163 {
164 wxObject *obj = (wxObject *)current->Data() ;
165 // Do a recursive search.
166 wxWindow *parent = (wxWindow *)obj ;
167 wxWindow *wnd = parent->FindItemByHWND(hWnd) ;
168 if ( wnd )
169 return wnd ;
170
171 if ( (!controlOnly) || obj->IsKindOf(CLASSINFO(wxControl)) )
172 {
173 wxWindow *item = (wxWindow *)current->Data();
174 if ( (HWND)(item->GetHWND()) == (HWND) hWnd )
175 return item;
176 else
177 {
178 if ( item->ContainsHWND(hWnd) )
179 return item;
180 }
181 }
182 current = current->Next();
183 }
184 return NULL;
185 }
186
187 // Default command handler
188 bool wxWindow::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
189 {
190 return FALSE;
191 }
192
193 bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
194 WXLPARAM lParam,
195 WXLPARAM* WXUNUSED(result))
196 {
197 #ifdef __WIN95__
198 #if wxUSE_TOOLTIPS
199 NMHDR* hdr = (NMHDR *)lParam;
200 if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
201 {
202 TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
203 ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
204
205 // processed
206 return TRUE;
207 }
208 #endif
209 #endif
210
211 return FALSE;
212 }
213
214 void wxWindow::PreDelete(WXHDC WXUNUSED(dc))
215 {
216 }
217
218 // ----------------------------------------------------------------------------
219 // constructors and such
220 // ----------------------------------------------------------------------------
221
222 void wxWindow::Init()
223 {
224 // generic
225 InitBase();
226
227 // MSW specific
228 m_doubleClickAllowed = 0 ;
229 m_winCaptured = FALSE;
230
231 // caret stuff: initially there is no caret at all
232 m_caretWidth =
233 m_caretHeight = 0;
234 m_caretEnabled =
235 m_caretShown = FALSE;
236
237 m_inOnSize = FALSE;
238
239 m_isBeingDeleted = FALSE;
240 m_oldWndProc = 0;
241 m_useCtl3D = FALSE;
242 m_mouseInWindow = FALSE;
243
244 // wxWnd
245 m_lastMsg = 0;
246 m_lastWParam = 0;
247 m_lastLParam = 0;
248 m_hMenu = 0;
249
250 m_xThumbSize = 0;
251 m_yThumbSize = 0;
252 m_backgroundTransparent = FALSE;
253
254 m_lastMouseX =
255 m_lastMouseY = -1;
256 m_lastMouseEvent = -1;
257 }
258
259 // Destructor
260 wxWindow::~wxWindow()
261 {
262 m_isBeingDeleted = TRUE;
263
264 MSWDetachWindowMenu();
265
266 if ( m_hWnd )
267 ::DestroyWindow((HWND)m_hWnd);
268
269 wxRemoveHandleAssociation(this);
270 m_hWnd = 0;
271
272 // Restore old Window proc, if required and remove hWnd <-> wxWindow
273 // association
274 UnsubclassWin();
275 }
276
277 extern char wxCanvasClassName[];
278
279 // real construction (Init() must have been called before!)
280 bool wxWindow::Create(wxWindow *parent, wxWindowID id,
281 const wxPoint& pos,
282 const wxSize& size,
283 long style,
284 const wxString& name)
285 {
286 wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
287
288 parent->AddChild(this);
289
290 DWORD msflags = 0;
291 if ( style & wxBORDER )
292 msflags |= WS_BORDER;
293 if ( style & wxTHICK_FRAME )
294 msflags |= WS_THICKFRAME;
295
296 msflags |= WS_CHILD | WS_VISIBLE;
297 if ( style & wxCLIP_CHILDREN )
298 msflags |= WS_CLIPCHILDREN;
299
300 bool want3D;
301 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
302
303 // Even with extended styles, need to combine with WS_BORDER
304 // for them to look right.
305 if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
306 (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER))
307 {
308 msflags |= WS_BORDER;
309 }
310
311 MSWCreate(m_windowId, parent, wxCanvasClassName, this, NULL,
312 pos.x, pos.y,
313 WidthDefault(size.x), HeightDefault(size.y),
314 msflags, NULL, exStyle);
315
316 return TRUE;
317 }
318
319 void wxWindow::SetFocus()
320 {
321 HWND hWnd = (HWND) GetHWND();
322 if ( hWnd )
323 ::SetFocus(hWnd);
324 }
325
326 bool wxWindow::Enable(bool enable)
327 {
328 if ( !wxWindowBase::Enable(enable) )
329 return FALSE;
330
331 HWND hWnd = (HWND) GetHWND();
332 if ( hWnd )
333 ::EnableWindow(hWnd, (BOOL)enable);
334
335 return TRUE;
336 }
337
338 void wxWindow::CaptureMouse()
339 {
340 HWND hWnd = (HWND) GetHWND();
341 if ( hWnd && !m_winCaptured )
342 {
343 SetCapture(hWnd);
344 m_winCaptured = TRUE;
345 }
346 }
347
348 void wxWindow::ReleaseMouse()
349 {
350 if ( m_winCaptured )
351 {
352 ReleaseCapture();
353 m_winCaptured = FALSE;
354 }
355 }
356
357 #if wxUSE_DRAG_AND_DROP
358
359 void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
360 {
361 if ( m_dropTarget != 0 ) {
362 m_dropTarget->Revoke(m_hWnd);
363 delete m_dropTarget;
364 }
365
366 m_dropTarget = pDropTarget;
367 if ( m_dropTarget != 0 )
368 m_dropTarget->Register(m_hWnd);
369 }
370
371 #endif // wxUSE_DRAG_AND_DROP
372
373
374 //old style file-manager drag&drop support
375 // I think we should retain the old-style
376 // DragAcceptFiles in parallel with SetDropTarget.
377 // JACS
378 void wxWindow::DragAcceptFiles(bool accept)
379 {
380 HWND hWnd = (HWND) GetHWND();
381 if ( hWnd )
382 ::DragAcceptFiles(hWnd, (BOOL)accept);
383 }
384
385 // ----------------------------------------------------------------------------
386 // tooltips
387 // ----------------------------------------------------------------------------
388
389 #if wxUSE_TOOLTIPS
390
391 void wxWindow::DoSetToolTip(wxToolTip *tooltip)
392 {
393 wxWindowBase::SetToolTip(tooltip);
394
395 if ( m_tooltip )
396 m_tooltip->SetWindow(this);
397 }
398
399 #endif // wxUSE_TOOLTIPS
400
401 // Get total size
402 void wxWindow::DoGetSize(int *x, int *y) const
403 {
404 HWND hWnd = (HWND) GetHWND();
405 RECT rect;
406 GetWindowRect(hWnd, &rect);
407
408 if ( x )
409 *x = rect.right - rect.left;
410 if ( y )
411 *y = rect.bottom - rect.top;
412 }
413
414 void wxWindow::DoGetPosition(int *x, int *y) const
415 {
416 HWND hWnd = (HWND) GetHWND();
417 HWND hParentWnd = 0;
418 if ( GetParent() )
419 hParentWnd = (HWND) GetParent()->GetHWND();
420
421 RECT rect;
422 GetWindowRect(hWnd, &rect);
423
424 // Since we now have the absolute screen coords, if there's a parent we
425 // must subtract its top left corner
426 POINT point;
427 point.x = rect.left;
428 point.y = rect.top;
429 if ( hParentWnd )
430 {
431 ::ScreenToClient(hParentWnd, &point);
432 }
433
434 // We may be faking the client origin. So a window that's really at (0,
435 // 30) may appear (to wxWin apps) to be at (0, 0).
436 if ( GetParent() )
437 {
438 wxPoint pt(GetParent()->GetClientAreaOrigin());
439 point.x -= pt.x;
440 point.y -= pt.y;
441 }
442
443 if ( x )
444 *x = point.x;
445 if ( y )
446 *y = point.y;
447 }
448
449 void wxWindow::ScreenToClient(int *x, int *y) const
450 {
451 POINT pt;
452 if ( x )
453 pt.x = *x;
454 if ( y )
455 pt.y = *y;
456
457 HWND hWnd = (HWND) GetHWND();
458 ::ScreenToClient(hWnd, &pt);
459
460 if ( x )
461 *x = pt.x;
462 if ( y )
463 *y = pt.y;
464 }
465
466 void wxWindow::ClientToScreen(int *x, int *y) const
467 {
468 POINT pt;
469 if ( x )
470 pt.x = *x;
471 if ( y )
472 pt.y = *y;
473
474 HWND hWnd = (HWND) GetHWND();
475 ::ClientToScreen(hWnd, &pt);
476
477 if ( x )
478 *x = pt.x;
479 if ( y )
480 *y = pt.y;
481 }
482
483 bool wxWindow::SetCursor(const wxCursor& cursor)
484 {
485 if ( !wxWindowBase::SetCursor(cursor) )
486 {
487 // no change
488 return FALSE;
489 }
490
491 wxASSERT_MSG( m_cursor.Ok(),
492 _T("cursor must be valid after call to the base version"));
493
494 HWND hWnd = (HWND)GetHWND();
495
496 // Change the cursor NOW if we're within the correct window
497 POINT point;
498 ::GetCursorPos(&point);
499
500 RECT rect;
501 ::GetWindowRect(hWnd, &rect);
502
503 if ( ::PtInRect(&rect, point) && !wxIsBusy() )
504 ::SetCursor((HCURSOR)m_cursor.GetHCURSOR());
505
506 return TRUE;
507 }
508
509 // Get size *available for subwindows* i.e. excluding menu bar etc.
510 void wxWindow::DoGetClientSize(int *x, int *y) const
511 {
512 HWND hWnd = (HWND) GetHWND();
513 RECT rect;
514 ::GetClientRect(hWnd, &rect);
515 if ( x )
516 *x = rect.right;
517 if ( y )
518 *y = rect.bottom;
519 }
520
521 void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
522 {
523 int currentX, currentY;
524 GetPosition(&currentX, &currentY);
525 int currentW,currentH;
526 GetSize(&currentW, &currentH);
527
528 if ( x == currentX && y == currentY && width == currentW && height == currentH )
529 return;
530
531 int actualWidth = width;
532 int actualHeight = height;
533 int actualX = x;
534 int actualY = y;
535 if ( x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
536 actualX = currentX;
537 if ( y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
538 actualY = currentY;
539
540 AdjustForParentClientOrigin(actualX, actualY, sizeFlags);
541
542 if ( width == -1 )
543 actualWidth = currentW ;
544 if ( height == -1 )
545 actualHeight = currentH ;
546
547 HWND hWnd = (HWND) GetHWND();
548 if ( hWnd )
549 MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE);
550 }
551
552 void wxWindow::DoSetClientSize(int width, int height)
553 {
554 wxWindow *parent = GetParent();
555 HWND hWnd = (HWND) GetHWND();
556 HWND hParentWnd = (HWND) 0;
557 if ( parent )
558 hParentWnd = (HWND) parent->GetHWND();
559
560 RECT rect;
561 ::GetClientRect(hWnd, &rect);
562
563 RECT rect2;
564 GetWindowRect(hWnd, &rect2);
565
566 // Find the difference between the entire window (title bar and all)
567 // and the client area; add this to the new client size to move the
568 // window
569 int actual_width = rect2.right - rect2.left - rect.right + width;
570 int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
571
572 // If there's a parent, must subtract the parent's top left corner
573 // since MoveWindow moves relative to the parent
574
575 POINT point;
576 point.x = rect2.left;
577 point.y = rect2.top;
578 if ( parent )
579 {
580 ::ScreenToClient(hParentWnd, &point);
581 }
582
583 MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
584
585 wxSizeEvent event(wxSize(width, height), m_windowId);
586 event.SetEventObject(this);
587 GetEventHandler()->ProcessEvent(event);
588 }
589
590 // For implementation purposes - sometimes decorations make the client area
591 // smaller
592 wxPoint wxWindow::GetClientAreaOrigin() const
593 {
594 return wxPoint(0, 0);
595 }
596
597 // Makes an adjustment to the window position (for example, a frame that has
598 // a toolbar that it manages itself).
599 void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
600 {
601 if ( ((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent() )
602 {
603 wxPoint pt(GetParent()->GetClientAreaOrigin());
604 x += pt.x; y += pt.y;
605 }
606 }
607
608 bool wxWindow::Show(bool show)
609 {
610 if ( !wxWindowBase::Show(show) )
611 return FALSE;
612
613 HWND hWnd = (HWND) GetHWND();
614 int cshow = show ? SW_SHOW : SW_HIDE;
615 ::ShowWindow(hWnd, cshow);
616
617 if ( show )
618 {
619 BringWindowToTop(hWnd);
620 }
621
622 return TRUE;
623 }
624
625 int wxWindow::GetCharHeight(void) const
626 {
627 TEXTMETRIC lpTextMetric;
628 HWND hWnd = (HWND) GetHWND();
629 HDC dc = ::GetDC(hWnd);
630
631 GetTextMetrics(dc, &lpTextMetric);
632 ::ReleaseDC(hWnd, dc);
633
634 return lpTextMetric.tmHeight;
635 }
636
637 int wxWindow::GetCharWidth(void) const
638 {
639 TEXTMETRIC lpTextMetric;
640 HWND hWnd = (HWND) GetHWND();
641 HDC dc = ::GetDC(hWnd);
642
643 GetTextMetrics(dc, &lpTextMetric);
644 ::ReleaseDC(hWnd, dc);
645
646 return lpTextMetric.tmAveCharWidth;
647 }
648
649 void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
650 int *descent, int *externalLeading, const wxFont *theFont) const
651 {
652 wxFont *fontToUse = (wxFont *)theFont;
653 if ( !fontToUse )
654 fontToUse = (wxFont *) & m_font;
655
656 HWND hWnd = (HWND) GetHWND();
657 HDC dc = ::GetDC(hWnd);
658
659 HFONT fnt = 0;
660 HFONT was = 0;
661 if ( fontToUse && fontToUse->Ok() )
662 {
663 fnt = (HFONT)fontToUse->GetResourceHandle();
664 if ( fnt )
665 was = (HFONT) SelectObject(dc,fnt) ;
666 }
667
668 SIZE sizeRect;
669 TEXTMETRIC tm;
670 GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect);
671 GetTextMetrics(dc, &tm);
672
673 if ( fontToUse && fnt && was )
674 SelectObject(dc,was) ;
675
676 ReleaseDC(hWnd, dc);
677
678 *x = sizeRect.cx;
679 *y = sizeRect.cy;
680 if ( descent ) *descent = tm.tmDescent;
681 if ( externalLeading ) *externalLeading = tm.tmExternalLeading;
682
683 // if ( fontToUse )
684 // fontToUse->ReleaseResource();
685 }
686
687 void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
688 {
689 HWND hWnd = (HWND) GetHWND();
690 if ( hWnd )
691 {
692 if ( rect )
693 {
694 RECT mswRect;
695 mswRect.left = rect->x;
696 mswRect.top = rect->y;
697 mswRect.right = rect->x + rect->width;
698 mswRect.bottom = rect->y + rect->height;
699
700 ::InvalidateRect(hWnd, &mswRect, eraseBack);
701 }
702 else
703 ::InvalidateRect(hWnd, NULL, eraseBack);
704 }
705 }
706
707 bool wxWindow::ProcessEvent(wxEvent& event)
708 {
709 // we save here the information about the last message because it might be
710 // overwritten if the event handler sends any messages to our window (case
711 // in point: wxNotebook::OnSize) - and then if we call Default() later
712 // (which is done quite often if the message is not processed) it will use
713 // incorrect values for m_lastXXX variables
714 WXUINT lastMsg = m_lastMsg;
715 WXWPARAM lastWParam = m_lastWParam;
716 WXLPARAM lastLParam = m_lastLParam;
717
718 // call the base version
719 bool bProcessed = wxEvtHandler::ProcessEvent(event);
720
721 // restore
722 m_lastMsg = lastMsg;
723 m_lastWParam = lastWParam;
724 m_lastLParam = lastLParam;
725
726 return bProcessed;
727 }
728
729 // Hook for new window just as it's being created,
730 // when the window isn't yet associated with the handle
731 wxWindow *wxWndHook = NULL;
732
733 // Main window proc
734 LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
735 {
736 wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
737
738 if ( !wnd && wxWndHook )
739 {
740 wxAssociateWinWithHandle(hWnd, wxWndHook);
741 wnd = wxWndHook;
742 wxWndHook = NULL;
743 wnd->SetHWND((WXHWND)hWnd);
744 }
745
746 // Stop right here if we don't have a valid handle in our wxWindow object.
747 if ( wnd && !wnd->GetHWND() ) {
748 wnd->SetHWND((WXHWND) hWnd);
749 long res = wnd->MSWDefWindowProc(message, wParam, lParam );
750 wnd->SetHWND(0);
751 return res;
752 }
753
754 if ( wnd ) {
755 wnd->PushLastMessage(message, wParam, lParam);
756 }
757 if ( wnd )
758 return wnd->MSWWindowProc(message, wParam, lParam);
759 else
760 return DefWindowProc( hWnd, message, wParam, lParam );
761 }
762
763 // Should probably have a test for 'genuine' NT
764 #if defined(__WIN32__)
765 #define DIMENSION_TYPE short
766 #else
767 #define DIMENSION_TYPE int
768 #endif
769
770 // Main Windows window proc
771 long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
772 {
773 wxASSERT( m_lastMsg == message &&
774 m_lastWParam == wParam && m_lastLParam == lParam );
775
776 #ifdef __WXDEBUG__
777 wxLogTrace(wxTraceMessages, "Processing %s(%lx, %lx)",
778 wxGetMessageName(message), wParam, lParam);
779 #endif // __WXDEBUG__
780
781 HWND hWnd = (HWND)m_hWnd;
782
783 switch (message)
784 {
785 case WM_ACTIVATE:
786 {
787 #ifdef __WIN32__
788 WORD state = LOWORD(wParam);
789 WORD minimized = HIWORD(wParam);
790 HWND hwnd = (HWND)lParam;
791 #else
792 WORD state = (WORD)wParam;
793 WORD minimized = LOWORD(lParam);
794 HWND hwnd = (HWND)HIWORD(lParam);
795 #endif
796 MSWOnActivate(state, (minimized != 0), (WXHWND) hwnd);
797 return 0;
798 break;
799 }
800 case WM_SETFOCUS:
801 {
802 HWND hwnd = (HWND)wParam;
803 // return OnSetFocus(hwnd);
804
805 if ( MSWOnSetFocus((WXHWND) hwnd) )
806 return 0;
807 else return MSWDefWindowProc(message, wParam, lParam );
808 break;
809 }
810 case WM_KILLFOCUS:
811 {
812 HWND hwnd = (HWND)lParam;
813 // return OnKillFocus(hwnd);
814 if ( MSWOnKillFocus((WXHWND) hwnd) )
815 return 0;
816 else
817 return MSWDefWindowProc(message, wParam, lParam );
818 break;
819 }
820 case WM_CREATE:
821 {
822 MSWOnCreate((WXLPCREATESTRUCT) (LPCREATESTRUCT)lParam);
823 return 0;
824 break;
825 }
826 case WM_SHOWWINDOW:
827 {
828 MSWOnShow((wParam != 0), (int) lParam);
829 break;
830 }
831 case WM_PAINT:
832 {
833 if ( MSWOnPaint() )
834 return 0;
835 else return MSWDefWindowProc(message, wParam, lParam );
836 break;
837 }
838 case WM_QUERYDRAGICON:
839 {
840 HICON hIcon = (HICON)MSWOnQueryDragIcon();
841 if ( hIcon )
842 return (long)hIcon;
843 else
844 return MSWDefWindowProc(message, wParam, lParam );
845 break;
846 }
847
848 case WM_SIZE:
849 {
850 int width = LOWORD(lParam);
851 int height = HIWORD(lParam);
852 MSWOnSize(width, height, wParam);
853 break;
854 }
855
856 case WM_MOVE:
857 {
858 wxMoveEvent event(wxPoint(LOWORD(lParam), HIWORD(lParam)),
859 m_windowId);
860 event.SetEventObject(this);
861 if ( !GetEventHandler()->ProcessEvent(event) )
862 Default();
863 }
864 break;
865
866 case WM_WINDOWPOSCHANGING:
867 {
868 MSWOnWindowPosChanging((void *)lParam);
869 break;
870 }
871
872 case WM_RBUTTONDOWN:
873 {
874 int x = (DIMENSION_TYPE) LOWORD(lParam);
875 int y = (DIMENSION_TYPE) HIWORD(lParam);
876 MSWOnRButtonDown(x, y, wParam);
877 break;
878 }
879 case WM_RBUTTONUP:
880 {
881 int x = (DIMENSION_TYPE) LOWORD(lParam);
882 int y = (DIMENSION_TYPE) HIWORD(lParam);
883 MSWOnRButtonUp(x, y, wParam);
884 break;
885 }
886 case WM_RBUTTONDBLCLK:
887 {
888 int x = (DIMENSION_TYPE) LOWORD(lParam);
889 int y = (DIMENSION_TYPE) HIWORD(lParam);
890 MSWOnRButtonDClick(x, y, wParam);
891 break;
892 }
893 case WM_MBUTTONDOWN:
894 {
895 int x = (DIMENSION_TYPE) LOWORD(lParam);
896 int y = (DIMENSION_TYPE) HIWORD(lParam);
897 MSWOnMButtonDown(x, y, wParam);
898 break;
899 }
900 case WM_MBUTTONUP:
901 {
902 int x = (DIMENSION_TYPE) LOWORD(lParam);
903 int y = (DIMENSION_TYPE) HIWORD(lParam);
904 MSWOnMButtonUp(x, y, wParam);
905 break;
906 }
907 case WM_MBUTTONDBLCLK:
908 {
909 int x = (DIMENSION_TYPE) LOWORD(lParam);
910 int y = (DIMENSION_TYPE) HIWORD(lParam);
911 MSWOnMButtonDClick(x, y, wParam);
912 break;
913 }
914 case WM_LBUTTONDOWN:
915 {
916 int x = (DIMENSION_TYPE) LOWORD(lParam);
917 int y = (DIMENSION_TYPE) HIWORD(lParam);
918 MSWOnLButtonDown(x, y, wParam);
919 break;
920 }
921 case WM_LBUTTONUP:
922 {
923 int x = (DIMENSION_TYPE) LOWORD(lParam);
924 int y = (DIMENSION_TYPE) HIWORD(lParam);
925 MSWOnLButtonUp(x, y, wParam);
926 break;
927 }
928 case WM_LBUTTONDBLCLK:
929 {
930 int x = (DIMENSION_TYPE) LOWORD(lParam);
931 int y = (DIMENSION_TYPE) HIWORD(lParam);
932 MSWOnLButtonDClick(x, y, wParam);
933 break;
934 }
935 case WM_MOUSEMOVE:
936 {
937 int x = (DIMENSION_TYPE) LOWORD(lParam);
938 int y = (DIMENSION_TYPE) HIWORD(lParam);
939 MSWOnMouseMove(x, y, wParam);
940 break;
941 }
942 case MM_JOY1BUTTONDOWN:
943 {
944 int x = LOWORD(lParam);
945 int y = HIWORD(lParam);
946 MSWOnJoyDown(wxJOYSTICK1, x, y, wParam);
947 break;
948 }
949 case MM_JOY2BUTTONDOWN:
950 {
951 int x = LOWORD(lParam);
952 int y = HIWORD(lParam);
953 MSWOnJoyDown(wxJOYSTICK2, x, y, wParam);
954 break;
955 }
956 case MM_JOY1BUTTONUP:
957 {
958 int x = LOWORD(lParam);
959 int y = HIWORD(lParam);
960 MSWOnJoyUp(wxJOYSTICK1, x, y, wParam);
961 break;
962 }
963 case MM_JOY2BUTTONUP:
964 {
965 int x = LOWORD(lParam);
966 int y = HIWORD(lParam);
967 MSWOnJoyUp(wxJOYSTICK2, x, y, wParam);
968 break;
969 }
970 case MM_JOY1MOVE:
971 {
972 int x = LOWORD(lParam);
973 int y = HIWORD(lParam);
974 MSWOnJoyMove(wxJOYSTICK1, x, y, wParam);
975 break;
976 }
977 case MM_JOY2MOVE:
978 {
979 int x = LOWORD(lParam);
980 int y = HIWORD(lParam);
981 MSWOnJoyMove(wxJOYSTICK2, x, y, wParam);
982 break;
983 }
984 case MM_JOY1ZMOVE:
985 {
986 int z = LOWORD(lParam);
987 MSWOnJoyZMove(wxJOYSTICK1, z, wParam);
988 break;
989 }
990 case MM_JOY2ZMOVE:
991 {
992 int z = LOWORD(lParam);
993 MSWOnJoyZMove(wxJOYSTICK2, z, wParam);
994 break;
995 }
996 case WM_DESTROY:
997 {
998 if ( MSWOnDestroy() )
999 return 0;
1000 else return MSWDefWindowProc(message, wParam, lParam );
1001 break;
1002 }
1003 case WM_SYSCOMMAND:
1004 {
1005 return MSWOnSysCommand(wParam, lParam);
1006 break;
1007 }
1008
1009 case WM_COMMAND:
1010 {
1011 #ifdef __WIN32__
1012 WORD id = LOWORD(wParam);
1013 HWND hwnd = (HWND)lParam;
1014 WORD cmd = HIWORD(wParam);
1015 #else
1016 WORD id = (WORD)wParam;
1017 HWND hwnd = (HWND)LOWORD(lParam) ;
1018 WORD cmd = HIWORD(lParam);
1019 #endif
1020 if ( !MSWOnCommand(id, cmd, (WXHWND) hwnd) )
1021 return MSWDefWindowProc(message, wParam, lParam );
1022 break;
1023 }
1024 #if defined(__WIN95__)
1025 case WM_NOTIFY:
1026 {
1027 // for some messages (TVN_ITEMEXPANDING for example), the return
1028 // value of WM_NOTIFY handler is important, so don't just return 0
1029 // if we processed the message
1030 return MSWOnNotify(wParam, lParam);
1031 }
1032 #endif
1033 case WM_MENUSELECT:
1034 {
1035 #ifdef __WIN32__
1036 WORD flags = HIWORD(wParam);
1037 HMENU sysmenu = (HMENU)lParam;
1038 #else
1039 WORD flags = LOWORD(lParam);
1040 HMENU sysmenu = (HMENU)HIWORD(lParam);
1041 #endif
1042 MSWOnMenuHighlight((WORD)wParam, flags, (WXHMENU) sysmenu);
1043 break;
1044 }
1045 case WM_INITMENUPOPUP:
1046 {
1047 MSWOnInitMenuPopup((WXHMENU) (HMENU)wParam, (int)LOWORD(lParam), (HIWORD(lParam) != 0));
1048 break;
1049 }
1050 case WM_DRAWITEM:
1051 {
1052 return MSWOnDrawItem((int)wParam, (WXDRAWITEMSTRUCT *)lParam);
1053 break;
1054 }
1055 case WM_MEASUREITEM:
1056 {
1057 return MSWOnMeasureItem((int)wParam, (WXMEASUREITEMSTRUCT *)lParam);
1058 break;
1059 }
1060 case WM_KEYDOWN:
1061 // If this has been processed by an event handler,
1062 // return 0 now (we've handled it).
1063 if ( MSWOnKeyDown((WORD) wParam, lParam) )
1064 break;
1065
1066 // we consider these message "not interesting" to OnChar
1067 if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
1068 {
1069 return Default();
1070 }
1071
1072 switch ( wParam )
1073 {
1074 // avoid duplicate messages to OnChar for these ASCII keys: they
1075 // will be translated by TranslateMessage() and received in WM_CHAR
1076 case VK_ESCAPE:
1077 case VK_SPACE:
1078 case VK_RETURN:
1079 case VK_BACK:
1080 case VK_TAB:
1081 return Default();
1082
1083 #ifdef VK_APPS
1084
1085 // normally these macros would be defined in windows.h
1086 #ifndef GET_X_LPARAM
1087 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
1088 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
1089 #endif
1090
1091 // special case of VK_APPS: treat it the same as right mouse click
1092 // because both usually pop up a context menu
1093 case VK_APPS:
1094 {
1095 // construct the key mask
1096 WPARAM fwKeys = MK_RBUTTON;
1097 if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
1098 fwKeys |= MK_CONTROL;
1099 if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
1100 fwKeys |= MK_SHIFT;
1101
1102 // simulate right mouse button click
1103 DWORD dwPos = ::GetMessagePos();
1104 int x = GET_X_LPARAM(dwPos),
1105 y = GET_Y_LPARAM(dwPos);
1106
1107 ScreenToClient(&x, &y);
1108 MSWOnRButtonDown(x, y, fwKeys);
1109 }
1110 break;
1111 #endif // VK_APPS
1112
1113 case VK_LEFT:
1114 case VK_RIGHT:
1115 case VK_DOWN:
1116 case VK_UP:
1117 default:
1118 if ( !MSWOnChar((WORD)wParam, lParam) )
1119 {
1120 return Default();
1121 }
1122 break;
1123 }
1124 break;
1125
1126 case WM_KEYUP:
1127 if ( !MSWOnKeyUp((WORD) wParam, lParam) )
1128 return Default();
1129 break;
1130
1131 case WM_CHAR: // Always an ASCII character
1132 if ( !MSWOnChar((WORD)wParam, lParam, TRUE) )
1133 return Default();
1134 break;
1135
1136 case WM_HSCROLL:
1137 {
1138 #ifdef __WIN32__
1139 WORD code = LOWORD(wParam);
1140 WORD pos = HIWORD(wParam);
1141 HWND control = (HWND)lParam;
1142 #else
1143 WORD code = (WORD)wParam;
1144 WORD pos = LOWORD(lParam);
1145 HWND control = (HWND)HIWORD(lParam);
1146 #endif
1147 MSWOnHScroll(code, pos, (WXHWND) control);
1148 break;
1149 }
1150 case WM_VSCROLL:
1151 {
1152 #ifdef __WIN32__
1153 WORD code = LOWORD(wParam);
1154 WORD pos = HIWORD(wParam);
1155 HWND control = (HWND)lParam;
1156 #else
1157 WORD code = (WORD)wParam;
1158 WORD pos = LOWORD(lParam);
1159 HWND control = (HWND)HIWORD(lParam);
1160 #endif
1161 MSWOnVScroll(code, pos, (WXHWND) control);
1162 break;
1163 }
1164 #ifdef __WIN32__
1165 case WM_CTLCOLORBTN:
1166 {
1167 int nCtlColor = CTLCOLOR_BTN;
1168 HWND control = (HWND)lParam;
1169 HDC pDC = (HDC)wParam;
1170 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1171 message, wParam, lParam);
1172 break;
1173 }
1174 case WM_CTLCOLORDLG:
1175 {
1176 int nCtlColor = CTLCOLOR_DLG;
1177 HWND control = (HWND)lParam;
1178 HDC pDC = (HDC)wParam;
1179 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1180 message, wParam, lParam);\
1181 break;
1182 }
1183 case WM_CTLCOLORLISTBOX:
1184 {
1185 int nCtlColor = CTLCOLOR_LISTBOX;
1186 HWND control = (HWND)lParam;
1187 HDC pDC = (HDC)wParam;
1188 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1189 message, wParam, lParam);
1190 break;
1191 }
1192 case WM_CTLCOLORMSGBOX:
1193 {
1194 int nCtlColor = CTLCOLOR_MSGBOX;
1195 HWND control = (HWND)lParam;
1196 HDC pDC = (HDC)wParam;
1197 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1198 message, wParam, lParam);
1199 break;
1200 }
1201 case WM_CTLCOLORSCROLLBAR:
1202 {
1203 int nCtlColor = CTLCOLOR_SCROLLBAR;
1204 HWND control = (HWND)lParam;
1205 HDC pDC = (HDC)wParam;
1206 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1207 message, wParam, lParam);
1208 break;
1209 }
1210 case WM_CTLCOLORSTATIC:
1211 {
1212 int nCtlColor = CTLCOLOR_STATIC;
1213 HWND control = (HWND)lParam;
1214 HDC pDC = (HDC)wParam;
1215 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1216 message, wParam, lParam);
1217 break;
1218 }
1219 case WM_CTLCOLOREDIT:
1220 {
1221 int nCtlColor = CTLCOLOR_EDIT;
1222 HWND control = (HWND)lParam;
1223 HDC pDC = (HDC)wParam;
1224 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1225 message, wParam, lParam);
1226 break;
1227 }
1228 #else
1229 case WM_CTLCOLOR:
1230 {
1231 HWND control = (HWND)LOWORD(lParam);
1232 int nCtlColor = (int)HIWORD(lParam);
1233 HDC pDC = (HDC)wParam;
1234 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1235 message, wParam, lParam);
1236 break;
1237 }
1238 #endif
1239 case WM_SYSCOLORCHANGE:
1240 {
1241 // Return value of 0 means, we processed it.
1242 if ( MSWOnColorChange((WXHWND) hWnd, message, wParam, lParam) == 0 )
1243 return 0;
1244 else
1245 return MSWDefWindowProc(message, wParam, lParam );
1246 break;
1247 }
1248 case WM_PALETTECHANGED:
1249 {
1250 return MSWOnPaletteChanged((WXHWND) (HWND) wParam);
1251 break;
1252 }
1253 case WM_QUERYNEWPALETTE:
1254 {
1255 return MSWOnQueryNewPalette();
1256 break;
1257 }
1258 case WM_ERASEBKGND:
1259 {
1260 // Prevents flicker when dragging
1261 if ( IsIconic(hWnd) ) return 1;
1262
1263 if ( !MSWOnEraseBkgnd((WXHDC) (HDC)wParam) )
1264 return 0; // Default(); MSWDefWindowProc(message, wParam, lParam );
1265 else return 1;
1266 break;
1267 }
1268 case WM_MDIACTIVATE:
1269 {
1270 #ifdef __WIN32__
1271 HWND hWndActivate = GET_WM_MDIACTIVATE_HWNDACTIVATE(wParam,lParam);
1272 HWND hWndDeactivate = GET_WM_MDIACTIVATE_HWNDDEACT(wParam,lParam);
1273 BOOL activate = GET_WM_MDIACTIVATE_FACTIVATE(hWnd,wParam,lParam);
1274 return MSWOnMDIActivate((long) activate, (WXHWND) hWndActivate, (WXHWND) hWndDeactivate);
1275 #else
1276 return MSWOnMDIActivate((BOOL)wParam, (HWND)LOWORD(lParam),
1277 (HWND)HIWORD(lParam));
1278 #endif
1279 }
1280 case WM_DROPFILES:
1281 {
1282 MSWOnDropFiles(wParam);
1283 break;
1284 }
1285 case WM_INITDIALOG:
1286 {
1287 return 0; // MSWOnInitDialog((WXHWND)(HWND)wParam);
1288 break;
1289 }
1290 case WM_QUERYENDSESSION:
1291 {
1292 // Same as WM_CLOSE, but inverted results. Thx Microsoft :-)
1293 // return MSWOnClose();
1294
1295 return MSWOnQueryEndSession(lParam);
1296 break;
1297 }
1298 case WM_ENDSESSION:
1299 {
1300 // Same as WM_CLOSE, but inverted results. Thx Microsoft :-)
1301 MSWOnEndSession((wParam != 0), lParam);
1302 return 0L;
1303 break;
1304 }
1305 case WM_CLOSE:
1306 {
1307 if ( MSWOnClose() )
1308 return 0L;
1309 else
1310 return 1L;
1311 break;
1312 }
1313 case WM_GETMINMAXINFO:
1314 {
1315 MINMAXINFO *info = (MINMAXINFO *)lParam;
1316 if ( m_minWidth != -1 )
1317 info->ptMinTrackSize.x = m_minWidth;
1318 if ( m_minHeight != -1 )
1319 info->ptMinTrackSize.y = m_minHeight;
1320 if ( m_maxWidth != -1 )
1321 info->ptMaxTrackSize.x = m_maxWidth;
1322 if ( m_maxHeight != -1 )
1323 info->ptMaxTrackSize.y = m_maxHeight;
1324 return MSWDefWindowProc(message, wParam, lParam );
1325 break;
1326 }
1327 case WM_GETDLGCODE:
1328 {
1329 return MSWGetDlgCode();
1330 }
1331 case WM_SETCURSOR:
1332 {
1333 // don't set cursor for other windows, only for this one: this
1334 // prevents children of this window from getting the same cursor
1335 // as the parent has (don't forget that this message is propagated
1336 // by default up the window parent-child hierarchy)
1337 if ( (HWND)wParam == hWnd )
1338 {
1339 // don't set cursor when the mouse is not in the client part
1340 short nHitTest = LOWORD(lParam);
1341 if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
1342 {
1343 HCURSOR hcursor = 0;
1344 if ( wxIsBusy() )
1345 {
1346 // from msw\utils.cpp
1347 extern HCURSOR gs_wxBusyCursor;
1348
1349 hcursor = gs_wxBusyCursor;
1350 }
1351 else
1352 {
1353 wxCursor *cursor = NULL;
1354
1355 if ( m_cursor.Ok() )
1356 {
1357 cursor = &m_cursor;
1358 }
1359 else
1360 {
1361 // from msw\data.cpp
1362 extern wxCursor *g_globalCursor;
1363
1364 if ( g_globalCursor && g_globalCursor->Ok() )
1365 cursor = g_globalCursor;
1366 }
1367
1368 if ( cursor )
1369 hcursor = (HCURSOR)cursor->GetHCURSOR();
1370 }
1371
1372 if ( hcursor )
1373 {
1374 ::SetCursor(hcursor);
1375
1376 // returning TRUE stops the DefWindowProc() from
1377 // further processing this message - exactly what we
1378 // need because we've just set the cursor.
1379 return TRUE;
1380 }
1381 }
1382 }
1383 }
1384 return MSWDefWindowProc(message, wParam, lParam );
1385
1386 default:
1387 return MSWDefWindowProc(message, wParam, lParam );
1388 }
1389
1390 return 0; // Success: we processed this command.
1391 }
1392
1393 // Dialog window proc
1394 LONG APIENTRY _EXPORT
1395 wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1396 {
1397 return 0;
1398 }
1399
1400 wxList *wxWinHandleList = NULL;
1401 wxWindow *wxFindWinFromHandle(WXHWND hWnd)
1402 {
1403 wxNode *node = wxWinHandleList->Find((long)hWnd);
1404 if ( !node )
1405 return NULL;
1406 return (wxWindow *)node->Data();
1407 }
1408
1409 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
1410 {
1411 // adding NULL hWnd is (first) surely a result of an error and
1412 // (secondly) breaks menu command processing
1413 wxCHECK_RET( hWnd != (HWND) NULL, "attempt to add a NULL hWnd to window list" );
1414
1415 if ( !wxWinHandleList->Find((long)hWnd) )
1416 wxWinHandleList->Append((long)hWnd, win);
1417 }
1418
1419 void wxRemoveHandleAssociation(wxWindow *win)
1420 {
1421 wxWinHandleList->DeleteObject(win);
1422 }
1423
1424 // Default destroyer - override if you destroy it in some other way
1425 // (e.g. with MDI child windows)
1426 void wxWindow::MSWDestroyWindow()
1427 {
1428 }
1429
1430 void wxWindow::MSWCreate(int id, wxWindow *parent, const char *wclass, wxWindow *wx_win, const char *title,
1431 int x, int y, int width, int height,
1432 WXDWORD style, const char *dialog_template, WXDWORD extendedStyle)
1433 {
1434 bool is_dialog = (dialog_template != NULL);
1435 int x1 = CW_USEDEFAULT;
1436 int y1 = 0;
1437 int width1 = CW_USEDEFAULT;
1438 int height1 = 100;
1439
1440 // Find parent's size, if it exists, to set up a possible default
1441 // panel size the size of the parent window
1442 RECT parent_rect;
1443 if ( parent )
1444 {
1445 // Was GetWindowRect: JACS 5/5/95
1446 ::GetClientRect((HWND) parent->GetHWND(), &parent_rect);
1447
1448 width1 = parent_rect.right - parent_rect.left;
1449 height1 = parent_rect.bottom - parent_rect.top;
1450 }
1451
1452 if ( x > -1 ) x1 = x;
1453 if ( y > -1 ) y1 = y;
1454 if ( width > -1 ) width1 = width;
1455 if ( height > -1 ) height1 = height;
1456
1457 HWND hParent = NULL;
1458 if ( parent )
1459 hParent = (HWND) parent->GetHWND();
1460
1461 wxWndHook = this;
1462
1463 if ( is_dialog )
1464 {
1465 // MakeProcInstance doesn't seem to be needed in C7. Is it needed for
1466 // other compilers???
1467 // VZ: it's always needed for Win16 and never for Win32
1468 #ifdef __WIN32__
1469 m_hWnd = (WXHWND) ::CreateDialog(wxGetInstance(), dialog_template, hParent,
1470 (DLGPROC)wxDlgProc);
1471 #else
1472 // N.B.: if we _don't_ use this form,
1473 // then with VC++ 1.5, it crashes horribly.
1474 #if 1
1475 m_hWnd = (WXHWND) ::CreateDialog(wxGetInstance(), dialog_template, hParent,
1476 (DLGPROC)wxDlgProc);
1477 #else
1478 // Crashes when we use this.
1479 DLGPROC dlgproc = (DLGPROC)MakeProcInstance((DLGPROC)wxWndProc, wxGetInstance());
1480
1481 m_hWnd = (WXHWND) ::CreateDialog(wxGetInstance(), dialog_template, hParent,
1482 (DLGPROC)dlgproc);
1483 #endif
1484 #endif
1485
1486 if ( m_hWnd == 0 )
1487 MessageBox(NULL, "Can't find dummy dialog template!\nCheck resource include path for finding wx.rc.",
1488 "wxWindows Error", MB_ICONEXCLAMATION | MB_OK);
1489 else MoveWindow((HWND) m_hWnd, x1, y1, width1, height1, FALSE);
1490 }
1491 else
1492 {
1493 int controlId = 0;
1494 if ( style & WS_CHILD )
1495 controlId = id;
1496 if ( !title )
1497 title = "";
1498
1499 m_hWnd = (WXHWND)CreateWindowEx(extendedStyle, wclass,
1500 title,
1501 style,
1502 x1, y1,
1503 width1, height1,
1504 hParent, (HMENU)controlId, wxGetInstance(),
1505 NULL);
1506
1507 if ( !m_hWnd ) {
1508 wxLogError("Can't create window of class %s!\n"
1509 "Possible Windows 3.x compatibility problem?", wclass);
1510 }
1511 }
1512
1513 wxWndHook = NULL;
1514 wxWinHandleList->Append((long)m_hWnd, this);
1515 }
1516
1517 void wxWindow::MSWOnCreate(WXLPCREATESTRUCT WXUNUSED(cs))
1518 {
1519 }
1520
1521 bool wxWindow::MSWOnClose()
1522 {
1523 return FALSE;
1524 }
1525
1526 // Some compilers don't define this
1527 #ifndef ENDSESSION_LOGOFF
1528 #define ENDSESSION_LOGOFF 0x80000000
1529 #endif
1530
1531 // Return TRUE to end session, FALSE to veto end session.
1532 bool wxWindow::MSWOnQueryEndSession(long logOff)
1533 {
1534 wxCloseEvent event(wxEVT_QUERY_END_SESSION, -1);
1535 event.SetEventObject(wxTheApp);
1536 event.SetCanVeto(TRUE);
1537 event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
1538 if ( (this == wxTheApp->GetTopWindow() ) && // Only send once
1539 wxTheApp->ProcessEvent(event) && event.GetVeto())
1540 {
1541 return FALSE; // Veto!
1542 }
1543 else
1544 {
1545 return TRUE; // Don't veto
1546 }
1547 }
1548
1549 bool wxWindow::MSWOnEndSession(bool endSession, long logOff)
1550 {
1551 wxCloseEvent event(wxEVT_END_SESSION, -1);
1552 event.SetEventObject(wxTheApp);
1553 event.SetCanVeto(FALSE);
1554 event.SetLoggingOff( (logOff == ENDSESSION_LOGOFF) );
1555 if (endSession && // No need to send if the session isn't ending
1556 (this == wxTheApp->GetTopWindow()) && // Only send once
1557 wxTheApp->ProcessEvent(event))
1558 {
1559 }
1560 return TRUE;
1561 }
1562
1563 bool wxWindow::MSWOnDestroy()
1564 {
1565 // delete our drop target if we've got one
1566 #if wxUSE_DRAG_AND_DROP
1567 if ( m_dropTarget != NULL ) {
1568 m_dropTarget->Revoke(m_hWnd);
1569
1570 delete m_dropTarget;
1571 m_dropTarget = NULL;
1572 }
1573 #endif
1574
1575 return TRUE;
1576 }
1577
1578 // Deal with child commands from buttons etc.
1579
1580 long wxWindow::MSWOnNotify(WXWPARAM wParam, WXLPARAM lParam)
1581 {
1582 #if defined(__WIN95__)
1583 // Find a child window to send the notification to, e.g. a toolbar.
1584 // There's a problem here. NMHDR::hwndFrom doesn't give us the
1585 // handle of the toolbar; it's probably the handle of the tooltip
1586 // window (anyway, it's parent is also the toolbar's parent).
1587 // So, since we don't know which hWnd or wxWindow originated the
1588 // WM_NOTIFY, we'll need to go through all the children of this window
1589 // trying out MSWNotify.
1590 // This won't work now, though, because any number of controls
1591 // could respond to the same generic messages :-(
1592
1593 /* This doesn't work for toolbars, but try for other controls first.
1594 */
1595 NMHDR *hdr = (NMHDR *)lParam;
1596 HWND hWnd = (HWND)hdr->hwndFrom;
1597 wxWindow *win = wxFindWinFromHandle((WXHWND) hWnd);
1598
1599 WXLPARAM result = 0;
1600
1601 if ( win )
1602 {
1603 if ( win->MSWNotify(wParam, lParam, &result) )
1604 return result;
1605 }
1606 else
1607 {
1608 // Rely on MSWNotify to check whether the message
1609 // belongs to the window or not
1610 wxNode *node = GetChildren().First();
1611 while (node)
1612 {
1613 wxWindow *child = (wxWindow *)node->Data();
1614 if ( child->MSWNotify(wParam, lParam, &result) )
1615 return result;
1616 node = node->Next();
1617 }
1618
1619 // finally try this window too (catches toolbar case)
1620 if ( MSWNotify(wParam, lParam, &result) )
1621 return result;
1622 }
1623 #endif // Win95
1624
1625 // not processed
1626 return Default();
1627 }
1628
1629 void wxWindow::MSWOnMenuHighlight(WXWORD WXUNUSED(item), WXWORD WXUNUSED(flags), WXHMENU WXUNUSED(sysmenu))
1630 {
1631 }
1632
1633 void wxWindow::MSWOnInitMenuPopup(WXHMENU menu, int pos, bool isSystem)
1634 {
1635 }
1636
1637 bool wxWindow::MSWOnActivate(int state, bool WXUNUSED(minimized), WXHWND WXUNUSED(activate))
1638 {
1639 wxActivateEvent event(wxEVT_ACTIVATE, ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)),
1640 m_windowId);
1641 event.SetEventObject(this);
1642 GetEventHandler()->ProcessEvent(event);
1643 return 0;
1644 }
1645
1646 bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd))
1647 {
1648 // Deal with caret
1649 if ( m_caretEnabled && (m_caretWidth > 0) && (m_caretHeight > 0) )
1650 {
1651 ::CreateCaret((HWND) GetHWND(), NULL, m_caretWidth, m_caretHeight);
1652 if ( m_caretShown )
1653 ::ShowCaret((HWND) GetHWND());
1654 }
1655
1656 // panel wants to track the window which was the last to have focus in it
1657 wxWindow *parent = GetParent();
1658 if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
1659 {
1660 ((wxPanel *)parent)->SetLastFocus(GetId());
1661 }
1662
1663 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
1664 event.SetEventObject(this);
1665 if ( !GetEventHandler()->ProcessEvent(event) )
1666 Default();
1667 return TRUE;
1668 }
1669
1670 bool wxWindow::MSWOnKillFocus(WXHWND WXUNUSED(hwnd))
1671 {
1672 // Deal with caret
1673 if ( m_caretEnabled )
1674 {
1675 ::DestroyCaret();
1676 }
1677
1678 wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
1679 event.SetEventObject(this);
1680 if ( !GetEventHandler()->ProcessEvent(event) )
1681 Default();
1682 return TRUE;
1683 }
1684
1685 void wxWindow::MSWOnDropFiles(WXWPARAM wParam)
1686 {
1687
1688 HDROP hFilesInfo = (HDROP) wParam;
1689 POINT dropPoint;
1690 DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
1691
1692 // Get the total number of files dropped
1693 WORD gwFilesDropped = (WORD)DragQueryFile ((HDROP)hFilesInfo,
1694 (UINT)-1,
1695 (LPSTR)0,
1696 (UINT)0);
1697
1698 wxString *files = new wxString[gwFilesDropped];
1699 int wIndex;
1700 for (wIndex=0; wIndex < (int)gwFilesDropped; wIndex++)
1701 {
1702 DragQueryFile (hFilesInfo, wIndex, (LPSTR) wxBuffer, 1000);
1703 files[wIndex] = wxBuffer;
1704 }
1705 DragFinish (hFilesInfo);
1706
1707 wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
1708 event.m_eventObject = this;
1709 event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y;
1710
1711 if ( !GetEventHandler()->ProcessEvent(event) )
1712 Default();
1713
1714 delete[] files;
1715 }
1716
1717 bool wxWindow::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
1718 {
1719 #if wxUSE_OWNER_DRAWN
1720 if ( id == 0 ) { // is it a menu item?
1721 DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
1722 wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
1723 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
1724
1725 // prepare to call OnDrawItem()
1726 wxDC dc;
1727 dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE);
1728 wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top,
1729 pDrawStruct->rcItem.right - pDrawStruct->rcItem.left,
1730 pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top);
1731 return pMenuItem->OnDrawItem(
1732 dc, rect,
1733 (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction,
1734 (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState
1735 );
1736 }
1737 #endif // owner-drawn menus
1738
1739 wxWindow *item = FindItem(id);
1740 #if wxUSE_DYNAMIC_CLASSES
1741 if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
1742 {
1743 return ((wxControl *)item)->MSWOnDraw(itemStruct);
1744 }
1745 else
1746 #endif
1747 return FALSE;
1748 }
1749
1750 bool wxWindow::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
1751 {
1752 #if wxUSE_OWNER_DRAWN
1753 if ( id == 0 ) { // is it a menu item?
1754 MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
1755 wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
1756 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
1757
1758 return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth,
1759 &pMeasureStruct->itemHeight);
1760 }
1761 #endif // owner-drawn menus
1762
1763 wxWindow *item = FindItem(id);
1764 #if wxUSE_DYNAMIC_CLASSES
1765 if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
1766 {
1767 return ((wxControl *)item)->MSWOnMeasure(itemStruct);
1768 }
1769 else
1770 #endif
1771 return FALSE;
1772 }
1773
1774 WXHBRUSH wxWindow::MSWOnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
1775 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
1776 {
1777 if ( nCtlColor == CTLCOLOR_DLG )
1778 {
1779 return OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
1780 }
1781
1782 wxControl *item = (wxControl *)FindItemByHWND(pWnd, TRUE);
1783
1784 WXHBRUSH hBrush = 0;
1785
1786 if ( item )
1787 hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
1788
1789 // I think that even for dialogs, we may need to call DefWindowProc (?)
1790 // Or maybe just rely on the usual default behaviour.
1791 if ( !hBrush )
1792 hBrush = (WXHBRUSH) MSWDefWindowProc(message, wParam, lParam);
1793
1794 return hBrush ;
1795 }
1796
1797 // Define for each class of dialog and control
1798 WXHBRUSH wxWindow::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
1799 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
1800 {
1801 return (WXHBRUSH) MSWDefWindowProc(message, wParam, lParam);
1802 }
1803
1804 bool wxWindow::MSWOnColorChange(WXHWND hWnd, WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
1805 {
1806 wxSysColourChangedEvent event;
1807 event.SetEventObject(this);
1808
1809 // Check if app handles this.
1810 if ( GetEventHandler()->ProcessEvent(event) )
1811 return 0;
1812
1813 // We didn't process it
1814 return 1;
1815 }
1816
1817 long wxWindow::MSWOnPaletteChanged(WXHWND hWndPalChange)
1818 {
1819 wxPaletteChangedEvent event(GetId());
1820 event.SetEventObject(this);
1821 event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
1822 GetEventHandler()->ProcessEvent(event);
1823 return 0;
1824 }
1825
1826 long wxWindow::MSWOnQueryNewPalette()
1827 {
1828 wxQueryNewPaletteEvent event(GetId());
1829 event.SetEventObject(this);
1830 if ( !GetEventHandler()->ProcessEvent(event) || !event.GetPaletteRealized() )
1831 {
1832 return (long) FALSE;
1833 }
1834 else
1835 return (long) TRUE;
1836 }
1837
1838 // Responds to colour changes: passes event on to children.
1839 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
1840 {
1841 wxNode *node = GetChildren().First();
1842 while ( node )
1843 {
1844 // Only propagate to non-top-level windows
1845 wxWindow *win = (wxWindow *)node->Data();
1846 if ( win->GetParent() )
1847 {
1848 wxSysColourChangedEvent event2;
1849 event.m_eventObject = win;
1850 win->GetEventHandler()->ProcessEvent(event2);
1851 }
1852
1853 node = node->Next();
1854 }
1855 }
1856
1857 long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
1858 {
1859 if ( m_oldWndProc )
1860 return ::CallWindowProc(CASTWNDPROC m_oldWndProc, (HWND) GetHWND(), (UINT) nMsg, (WPARAM) wParam, (LPARAM) lParam);
1861 else
1862 return ::DefWindowProc((HWND) GetHWND(), nMsg, wParam, lParam);
1863 }
1864
1865 long wxWindow::Default()
1866 {
1867 // Ignore 'fake' events (perhaps generated as a result of a separate real
1868 // event)
1869 if ( m_lastMsg == 0 )
1870 return 0;
1871
1872 #ifdef __WXDEBUG__
1873 wxLogTrace(wxTraceMessages, "Forwarding %s to DefWindowProc.",
1874 wxGetMessageName(m_lastMsg));
1875 #endif // __WXDEBUG__
1876
1877 return MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
1878 }
1879
1880 bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
1881 {
1882 if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) )
1883 {
1884 // intercept dialog navigation keys
1885 MSG *msg = (MSG *)pMsg;
1886 bool bProcess = TRUE;
1887 if ( msg->message != WM_KEYDOWN )
1888 bProcess = FALSE;
1889
1890 if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
1891 bProcess = FALSE;
1892
1893 if ( bProcess )
1894 {
1895 bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
1896
1897 // WM_GETDLGCODE: ask the control if it wants the key for itself,
1898 // don't process it if it's the case (except for Ctrl-Tab/Enter
1899 // combinations which are always processed)
1900 LONG lDlgCode = 0;
1901 if ( !bCtrlDown )
1902 {
1903 lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
1904 }
1905
1906 bool bForward = TRUE,
1907 bWindowChange = FALSE;
1908
1909 switch ( msg->wParam )
1910 {
1911 case VK_TAB:
1912 if ( lDlgCode & DLGC_WANTTAB ) {
1913 bProcess = FALSE;
1914 }
1915 else {
1916 // Ctrl-Tab cycles thru notebook pages
1917 bWindowChange = bCtrlDown;
1918 bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
1919 }
1920 break;
1921
1922 case VK_UP:
1923 case VK_LEFT:
1924 if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
1925 bProcess = FALSE;
1926 else
1927 bForward = FALSE;
1928 break;
1929
1930 case VK_DOWN:
1931 case VK_RIGHT:
1932 if ( (lDlgCode & DLGC_WANTARROWS) || bCtrlDown )
1933 bProcess = FALSE;
1934 break;
1935
1936 case VK_RETURN:
1937 {
1938 if ( lDlgCode & DLGC_WANTMESSAGE )
1939 {
1940 // control wants to process Enter itself, don't
1941 // call IsDialogMessage() which would interpret
1942 // it
1943 return FALSE;
1944 }
1945 #ifndef __WIN16__
1946 wxButton *btnDefault = GetDefaultItem();
1947 if ( btnDefault && !bCtrlDown )
1948 {
1949 // if there is a default button, Enter should
1950 // press it
1951 (void)::SendMessage((HWND)btnDefault->GetHWND(),
1952 BM_CLICK, 0, 0);
1953 return TRUE;
1954 }
1955 // else: but if there is not it makes sense to make it
1956 // work like a TAB - and that's what we do.
1957 // Note that Ctrl-Enter always works this way.
1958 #endif
1959 }
1960 break;
1961
1962 default:
1963 bProcess = FALSE;
1964 }
1965
1966 if ( bProcess )
1967 {
1968 wxNavigationKeyEvent event;
1969 event.SetDirection(bForward);
1970 event.SetWindowChange(bWindowChange);
1971 event.SetEventObject(this);
1972
1973 if ( GetEventHandler()->ProcessEvent(event) )
1974 return TRUE;
1975 }
1976 }
1977
1978 if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
1979 return TRUE;
1980 }
1981
1982 #if wxUSE_TOOLTIPS
1983 if ( m_tooltip )
1984 {
1985 // relay mouse move events to the tooltip control
1986 MSG *msg = (MSG *)pMsg;
1987 if ( msg->message == WM_MOUSEMOVE )
1988 m_tooltip->RelayEvent(pMsg);
1989 }
1990 #endif // wxUSE_TOOLTIPS
1991
1992 /* This code manages to disable character input completely. Nice one!
1993 * Probably because the dialog is requesting all char input. Or,
1994 * it gets called by non-dialog windows.
1995
1996 // In case we don't have wxTAB_TRAVERSAL style on.
1997 // If we don't call this, we may never process Enter correctly.
1998 if ( m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL) == 0 )
1999 {
2000 MSG *msg = (MSG *)pMsg;
2001 if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
2002 return TRUE;
2003 }
2004 */
2005 return FALSE;
2006 }
2007
2008 bool wxWindow::MSWTranslateMessage(WXMSG* pMsg)
2009 {
2010 if ( m_acceleratorTable.Ok( ) &&
2011 ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg))
2012 return TRUE;
2013 else
2014 return FALSE;
2015 }
2016
2017 long wxWindow::MSWOnMDIActivate(long WXUNUSED(flag), WXHWND WXUNUSED(activate), WXHWND WXUNUSED(deactivate))
2018 {
2019 return 1;
2020 }
2021
2022 void wxWindow::MSWDetachWindowMenu()
2023 {
2024 if ( m_hMenu )
2025 {
2026 int N = GetMenuItemCount((HMENU) m_hMenu);
2027 int i;
2028 for (i = 0; i < N; i++)
2029 {
2030 char buf[100];
2031 int chars = GetMenuString((HMENU) m_hMenu, i, buf, 100, MF_BYPOSITION);
2032 if ( (chars > 0) && (strcmp(buf, "&Window") == 0) )
2033 {
2034 RemoveMenu((HMENU) m_hMenu, i, MF_BYPOSITION);
2035 break;
2036 }
2037 }
2038 }
2039 }
2040
2041 bool wxWindow::MSWOnPaint()
2042 {
2043 #ifdef __WIN32__
2044 HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
2045 ::GetUpdateRgn((HWND) GetHWND(), hRegion, FALSE);
2046
2047 m_updateRegion = wxRegion((WXHRGN) hRegion);
2048 #else
2049 RECT updateRect;
2050 ::GetUpdateRect((HWND) GetHWND(), & updateRect, FALSE);
2051
2052 m_updateRegion = wxRegion(updateRect.left, updateRect.top,
2053 updateRect.right - updateRect.left, updateRect.bottom - updateRect.top);
2054 #endif
2055
2056 wxPaintEvent event(m_windowId);
2057 event.SetEventObject(this);
2058 if ( !GetEventHandler()->ProcessEvent(event) )
2059 Default();
2060 return TRUE;
2061 }
2062
2063 void wxWindow::MSWOnSize(int w, int h, WXUINT WXUNUSED(flag))
2064 {
2065 if ( m_inOnSize )
2066 return;
2067
2068 if ( !m_hWnd )
2069 return;
2070
2071 m_inOnSize = TRUE;
2072
2073 wxSizeEvent event(wxSize(w, h), m_windowId);
2074 event.SetEventObject(this);
2075 if ( !GetEventHandler()->ProcessEvent(event) )
2076 Default();
2077
2078 m_inOnSize = FALSE;
2079 }
2080
2081 void wxWindow::MSWOnWindowPosChanging(void *WXUNUSED(lpPos))
2082 {
2083 Default();
2084 }
2085
2086 // Deal with child commands from buttons etc.
2087 bool wxWindow::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
2088 {
2089 if ( wxCurrentPopupMenu )
2090 {
2091 wxMenu *popupMenu = wxCurrentPopupMenu;
2092 wxCurrentPopupMenu = NULL;
2093 bool succ = popupMenu->MSWCommand(cmd, id);
2094 return succ;
2095 }
2096
2097 wxWindow *item = FindItem(id);
2098 if ( item )
2099 {
2100 bool value = item->MSWCommand(cmd, id);
2101 return value;
2102 }
2103 else
2104 {
2105 wxWindow *win = wxFindWinFromHandle(control);
2106 if ( win )
2107 return win->MSWCommand(cmd, id);
2108 }
2109 return FALSE;
2110 }
2111
2112 long wxWindow::MSWOnSysCommand(WXWPARAM wParam, WXLPARAM lParam)
2113 {
2114 switch (wParam & 0xFFFFFFF0)
2115 {
2116 case SC_MAXIMIZE:
2117 {
2118 wxMaximizeEvent event(m_windowId);
2119 event.SetEventObject(this);
2120 if ( !GetEventHandler()->ProcessEvent(event) )
2121 return Default();
2122 else
2123 return 0;
2124 break;
2125 }
2126 case SC_MINIMIZE:
2127 {
2128 wxIconizeEvent event(m_windowId);
2129 event.SetEventObject(this);
2130 if ( !GetEventHandler()->ProcessEvent(event) )
2131 return Default();
2132 else
2133 return 0;
2134 break;
2135 }
2136 default:
2137 return Default();
2138 }
2139 return 0;
2140 }
2141
2142 void wxWindow::MSWOnLButtonDown(int x, int y, WXUINT flags)
2143 {
2144 wxMouseEvent event(wxEVT_LEFT_DOWN);
2145
2146 event.m_x = x; event.m_y = y;
2147 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2148 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2149 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2150 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2151 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2152 event.SetTimestamp(wxApp::sm_lastMessageTime);
2153 event.m_eventObject = this;
2154
2155 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_LEFT_DOWN;
2156
2157 if ( !GetEventHandler()->ProcessEvent(event) )
2158 Default();
2159 }
2160
2161 void wxWindow::MSWOnLButtonUp(int x, int y, WXUINT flags)
2162 {
2163 wxMouseEvent event(wxEVT_LEFT_UP);
2164
2165 event.m_x = x; event.m_y = y;
2166 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2167 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2168 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2169 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2170 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2171 event.SetTimestamp(wxApp::sm_lastMessageTime);
2172 event.m_eventObject = this;
2173
2174 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_LEFT_UP;
2175
2176 if ( !GetEventHandler()->ProcessEvent(event) )
2177 Default();
2178 }
2179
2180 void wxWindow::MSWOnLButtonDClick(int x, int y, WXUINT flags)
2181 {
2182 wxMouseEvent event(wxEVT_LEFT_DCLICK);
2183
2184 event.m_x = x; event.m_y = y;
2185 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2186 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2187 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2188 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2189 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2190 event.SetTimestamp(wxApp::sm_lastMessageTime);
2191 event.m_eventObject = this;
2192
2193 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_LEFT_DCLICK;
2194
2195 if ( !GetEventHandler()->ProcessEvent(event) )
2196 Default();
2197 }
2198
2199 void wxWindow::MSWOnMButtonDown(int x, int y, WXUINT flags)
2200 {
2201 wxMouseEvent event(wxEVT_MIDDLE_DOWN);
2202
2203 event.m_x = x; event.m_y = y;
2204 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2205 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2206 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2207 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2208 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2209 event.SetTimestamp(wxApp::sm_lastMessageTime);
2210 event.m_eventObject = this;
2211
2212 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_MIDDLE_DOWN;
2213
2214 if ( !GetEventHandler()->ProcessEvent(event) )
2215 Default();
2216 }
2217
2218 void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags)
2219 {
2220 wxMouseEvent event(wxEVT_MIDDLE_UP);
2221
2222 event.m_x = x; event.m_y = y;
2223 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2224 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2225 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2226 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2227 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2228 event.SetTimestamp(wxApp::sm_lastMessageTime);
2229 event.m_eventObject = this;
2230
2231 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_MIDDLE_UP;
2232
2233 if ( !GetEventHandler()->ProcessEvent(event) )
2234 Default();
2235 }
2236
2237 void wxWindow::MSWOnMButtonDClick(int x, int y, WXUINT flags)
2238 {
2239 wxMouseEvent event(wxEVT_MIDDLE_DCLICK);
2240
2241 event.m_x = x; event.m_y = y;
2242 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2243 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2244 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2245 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2246 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2247 event.SetTimestamp(wxApp::sm_lastMessageTime);
2248 event.m_eventObject = this;
2249
2250 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_MIDDLE_DCLICK;
2251
2252 if ( !GetEventHandler()->ProcessEvent(event) )
2253 Default();
2254 }
2255
2256 void wxWindow::MSWOnRButtonDown(int x, int y, WXUINT flags)
2257 {
2258 wxMouseEvent event(wxEVT_RIGHT_DOWN);
2259
2260 event.m_x = x; event.m_y = y;
2261 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2262 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2263 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2264 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2265 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2266 event.SetTimestamp(wxApp::sm_lastMessageTime);
2267 event.m_eventObject = this;
2268
2269 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_RIGHT_DOWN;
2270
2271 if ( !GetEventHandler()->ProcessEvent(event) )
2272 Default();
2273 }
2274
2275 void wxWindow::MSWOnRButtonUp(int x, int y, WXUINT flags)
2276 {
2277 wxMouseEvent event(wxEVT_RIGHT_UP);
2278
2279 event.m_x = x; event.m_y = y;
2280 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2281 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2282 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2283 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2284 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2285 event.m_eventObject = this;
2286 event.SetTimestamp(wxApp::sm_lastMessageTime);
2287
2288 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_RIGHT_UP;
2289
2290 if ( !GetEventHandler()->ProcessEvent(event) )
2291 Default();
2292 }
2293
2294 void wxWindow::MSWOnRButtonDClick(int x, int y, WXUINT flags)
2295 {
2296 wxMouseEvent event(wxEVT_RIGHT_DCLICK);
2297
2298 event.m_x = x; event.m_y = y;
2299 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2300 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2301 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2302 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2303 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2304 event.SetTimestamp(wxApp::sm_lastMessageTime);
2305 event.m_eventObject = this;
2306
2307 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y; m_lastMouseEvent = wxEVT_RIGHT_DCLICK;
2308
2309 if ( !GetEventHandler()->ProcessEvent(event) )
2310 Default();
2311 }
2312
2313 void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
2314 {
2315 // 'normal' move event...
2316
2317 if ( !m_mouseInWindow )
2318 {
2319 // Generate an ENTER event
2320 m_mouseInWindow = TRUE;
2321 MSWOnMouseEnter(x, y, flags);
2322 }
2323
2324 wxMouseEvent event(wxEVT_MOTION);
2325
2326 event.m_x = x; event.m_y = y;
2327 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2328 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2329 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2330 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2331 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2332 event.SetTimestamp(wxApp::sm_lastMessageTime);
2333 event.m_eventObject = this;
2334
2335 // Window gets a click down message followed by a mouse move
2336 // message even if position isn't changed! We want to discard
2337 // the trailing move event if x and y are the same.
2338 if ((m_lastMouseEvent == wxEVT_RIGHT_DOWN || m_lastMouseEvent == wxEVT_LEFT_DOWN ||
2339 m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
2340 (m_lastMouseX == event.m_x && m_lastMouseY == event.m_y))
2341 {
2342 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y;
2343 m_lastMouseEvent = wxEVT_MOTION;
2344 return;
2345 }
2346
2347 m_lastMouseEvent = wxEVT_MOTION;
2348 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y;
2349
2350 if ( !GetEventHandler()->ProcessEvent(event) )
2351 Default();
2352 }
2353
2354 void wxWindow::MSWOnMouseEnter(int x, int y, WXUINT flags)
2355 {
2356 wxMouseEvent event(wxEVT_ENTER_WINDOW);
2357
2358 event.m_x = x; event.m_y = y;
2359 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2360 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2361 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2362 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2363 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2364 event.SetTimestamp(wxApp::sm_lastMessageTime);
2365 event.m_eventObject = this;
2366
2367 m_lastMouseEvent = wxEVT_ENTER_WINDOW;
2368 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y;
2369 // No message - ensure we don't try to call the default behaviour accidentally.
2370 m_lastMsg = 0;
2371 GetEventHandler()->ProcessEvent(event);
2372 }
2373
2374 void wxWindow::MSWOnMouseLeave(int x, int y, WXUINT flags)
2375 {
2376 wxMouseEvent event(wxEVT_LEAVE_WINDOW);
2377
2378 event.m_x = x; event.m_y = y;
2379 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2380 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2381 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2382 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2383 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2384 event.SetTimestamp(wxApp::sm_lastMessageTime);
2385 event.m_eventObject = this;
2386
2387 m_lastMouseEvent = wxEVT_LEAVE_WINDOW;
2388 m_lastMouseX = event.m_x; m_lastMouseY = event.m_y;
2389 // No message - ensure we don't try to call the default behaviour accidentally.
2390 m_lastMsg = 0;
2391 GetEventHandler()->ProcessEvent(event);
2392 }
2393
2394 // isASCII is TRUE only when we're called from WM_CHAR handler and not from
2395 // WM_KEYDOWN one
2396 bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
2397 {
2398 int id;
2399 bool tempControlDown = FALSE;
2400 if ( isASCII )
2401 {
2402 // If 1 -> 26, translate to CTRL plus a letter.
2403 id = wParam;
2404 if ( (id > 0) && (id < 27) )
2405 {
2406 switch (id)
2407 {
2408 case 13:
2409 {
2410 id = WXK_RETURN;
2411 break;
2412 }
2413 case 8:
2414 {
2415 id = WXK_BACK;
2416 break;
2417 }
2418 case 9:
2419 {
2420 id = WXK_TAB;
2421 break;
2422 }
2423 default:
2424 {
2425 tempControlDown = TRUE;
2426 id = id + 96;
2427 }
2428 }
2429 }
2430 }
2431 else if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
2432 // it's ASCII and will be processed here only when called from
2433 // WM_CHAR (i.e. when isASCII = TRUE)
2434 id = -1;
2435 }
2436
2437 if ( id != -1 )
2438 {
2439 wxKeyEvent event(wxEVT_CHAR);
2440 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
2441 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
2442 if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
2443 event.m_altDown = TRUE;
2444
2445 event.m_eventObject = this;
2446 event.m_keyCode = id;
2447 event.SetTimestamp(wxApp::sm_lastMessageTime);
2448
2449 POINT pt ;
2450 GetCursorPos(&pt) ;
2451 RECT rect ;
2452 GetWindowRect((HWND) GetHWND(),&rect) ;
2453 pt.x -= rect.left ;
2454 pt.y -= rect.top ;
2455
2456 event.m_x = pt.x; event.m_y = pt.y;
2457
2458 if ( GetEventHandler()->ProcessEvent(event) )
2459 return TRUE;
2460 else
2461 return FALSE;
2462 }
2463 else
2464 return FALSE;
2465 }
2466
2467 bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam)
2468 {
2469 int id;
2470
2471 if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
2472 id = wParam;
2473 }
2474
2475 if ( id != -1 )
2476 {
2477 wxKeyEvent event(wxEVT_KEY_DOWN);
2478 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
2479 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
2480 if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
2481 event.m_altDown = TRUE;
2482
2483 event.m_eventObject = this;
2484 event.m_keyCode = id;
2485 event.SetTimestamp(wxApp::sm_lastMessageTime);
2486
2487 POINT pt ;
2488 GetCursorPos(&pt) ;
2489 RECT rect ;
2490 GetWindowRect((HWND) GetHWND(),&rect) ;
2491 pt.x -= rect.left ;
2492 pt.y -= rect.top ;
2493
2494 event.m_x = pt.x; event.m_y = pt.y;
2495
2496 if ( GetEventHandler()->ProcessEvent(event) )
2497 {
2498 return TRUE;
2499 }
2500 else return FALSE;
2501 }
2502 else
2503 {
2504 return FALSE;
2505 }
2506 }
2507
2508 bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam)
2509 {
2510 int id;
2511
2512 if ( (id = wxCharCodeMSWToWX(wParam)) == 0 ) {
2513 id = wParam;
2514 }
2515
2516 if ( id != -1 )
2517 {
2518 wxKeyEvent event(wxEVT_KEY_UP);
2519 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
2520 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
2521 if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
2522 event.m_altDown = TRUE;
2523
2524 event.m_eventObject = this;
2525 event.m_keyCode = id;
2526 event.SetTimestamp(wxApp::sm_lastMessageTime);
2527
2528 POINT pt ;
2529 GetCursorPos(&pt) ;
2530 RECT rect ;
2531 GetWindowRect((HWND) GetHWND(),&rect) ;
2532 pt.x -= rect.left ;
2533 pt.y -= rect.top ;
2534
2535 event.m_x = pt.x; event.m_y = pt.y;
2536
2537 if ( GetEventHandler()->ProcessEvent(event) )
2538 return TRUE;
2539 else
2540 return FALSE;
2541 }
2542 else
2543 return FALSE;
2544 }
2545
2546 void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags)
2547 {
2548 int buttons = 0;
2549 int change = 0;
2550 if ( flags & JOY_BUTTON1CHG )
2551 change = wxJOY_BUTTON1;
2552 if ( flags & JOY_BUTTON2CHG )
2553 change = wxJOY_BUTTON2;
2554 if ( flags & JOY_BUTTON3CHG )
2555 change = wxJOY_BUTTON3;
2556 if ( flags & JOY_BUTTON4CHG )
2557 change = wxJOY_BUTTON4;
2558
2559 if ( flags & JOY_BUTTON1 )
2560 buttons |= wxJOY_BUTTON1;
2561 if ( flags & JOY_BUTTON2 )
2562 buttons |= wxJOY_BUTTON2;
2563 if ( flags & JOY_BUTTON3 )
2564 buttons |= wxJOY_BUTTON3;
2565 if ( flags & JOY_BUTTON4 )
2566 buttons |= wxJOY_BUTTON4;
2567
2568 wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN, buttons, joystick, change);
2569 event.SetPosition(wxPoint(x, y));
2570 event.SetEventObject(this);
2571
2572 GetEventHandler()->ProcessEvent(event);
2573 }
2574
2575 void wxWindow::MSWOnJoyUp(int joystick, int x, int y, WXUINT flags)
2576 {
2577 int buttons = 0;
2578 int change = 0;
2579 if ( flags & JOY_BUTTON1CHG )
2580 change = wxJOY_BUTTON1;
2581 if ( flags & JOY_BUTTON2CHG )
2582 change = wxJOY_BUTTON2;
2583 if ( flags & JOY_BUTTON3CHG )
2584 change = wxJOY_BUTTON3;
2585 if ( flags & JOY_BUTTON4CHG )
2586 change = wxJOY_BUTTON4;
2587
2588 if ( flags & JOY_BUTTON1 )
2589 buttons |= wxJOY_BUTTON1;
2590 if ( flags & JOY_BUTTON2 )
2591 buttons |= wxJOY_BUTTON2;
2592 if ( flags & JOY_BUTTON3 )
2593 buttons |= wxJOY_BUTTON3;
2594 if ( flags & JOY_BUTTON4 )
2595 buttons |= wxJOY_BUTTON4;
2596
2597 wxJoystickEvent event(wxEVT_JOY_BUTTON_UP, buttons, joystick, change);
2598 event.SetPosition(wxPoint(x, y));
2599 event.SetEventObject(this);
2600
2601 GetEventHandler()->ProcessEvent(event);
2602 }
2603
2604 void wxWindow::MSWOnJoyMove(int joystick, int x, int y, WXUINT flags)
2605 {
2606 int buttons = 0;
2607 if ( flags & JOY_BUTTON1 )
2608 buttons |= wxJOY_BUTTON1;
2609 if ( flags & JOY_BUTTON2 )
2610 buttons |= wxJOY_BUTTON2;
2611 if ( flags & JOY_BUTTON3 )
2612 buttons |= wxJOY_BUTTON3;
2613 if ( flags & JOY_BUTTON4 )
2614 buttons |= wxJOY_BUTTON4;
2615
2616 wxJoystickEvent event(wxEVT_JOY_MOVE, buttons, joystick, 0);
2617 event.SetPosition(wxPoint(x, y));
2618 event.SetEventObject(this);
2619
2620 GetEventHandler()->ProcessEvent(event);
2621 }
2622
2623 void wxWindow::MSWOnJoyZMove(int joystick, int z, WXUINT flags)
2624 {
2625 int buttons = 0;
2626 if ( flags & JOY_BUTTON1 )
2627 buttons |= wxJOY_BUTTON1;
2628 if ( flags & JOY_BUTTON2 )
2629 buttons |= wxJOY_BUTTON2;
2630 if ( flags & JOY_BUTTON3 )
2631 buttons |= wxJOY_BUTTON3;
2632 if ( flags & JOY_BUTTON4 )
2633 buttons |= wxJOY_BUTTON4;
2634
2635 wxJoystickEvent event(wxEVT_JOY_ZMOVE, buttons, joystick, 0);
2636 event.SetZPosition(z);
2637 event.SetEventObject(this);
2638
2639 GetEventHandler()->ProcessEvent(event);
2640 }
2641
2642 void wxWindow::MSWOnVScroll(WXWORD wParam, WXWORD pos, WXHWND control)
2643 {
2644 if ( control )
2645 {
2646 wxWindow *child = wxFindWinFromHandle(control);
2647 if ( child )
2648 child->MSWOnVScroll(wParam, pos, control);
2649 return;
2650 }
2651
2652 wxScrollEvent event;
2653 event.SetPosition(pos);
2654 event.SetOrientation(wxVERTICAL);
2655 event.m_eventObject = this;
2656
2657 switch ( wParam )
2658 {
2659 case SB_TOP:
2660 event.m_eventType = wxEVT_SCROLL_TOP;
2661 break;
2662
2663 case SB_BOTTOM:
2664 event.m_eventType = wxEVT_SCROLL_BOTTOM;
2665 break;
2666
2667 case SB_LINEUP:
2668 event.m_eventType = wxEVT_SCROLL_LINEUP;
2669 break;
2670
2671 case SB_LINEDOWN:
2672 event.m_eventType = wxEVT_SCROLL_LINEDOWN;
2673 break;
2674
2675 case SB_PAGEUP:
2676 event.m_eventType = wxEVT_SCROLL_PAGEUP;
2677 break;
2678
2679 case SB_PAGEDOWN:
2680 event.m_eventType = wxEVT_SCROLL_PAGEDOWN;
2681 break;
2682
2683 case SB_THUMBTRACK:
2684 case SB_THUMBPOSITION:
2685 event.m_eventType = wxEVT_SCROLL_THUMBTRACK;
2686 break;
2687
2688 default:
2689 return;
2690 break;
2691 }
2692
2693 if ( !GetEventHandler()->ProcessEvent(event) )
2694 Default();
2695 }
2696
2697 void wxWindow::MSWOnHScroll( WXWORD wParam, WXWORD pos, WXHWND control)
2698 {
2699 if ( control )
2700 {
2701 wxWindow *child = wxFindWinFromHandle(control);
2702 if ( child ) {
2703 child->MSWOnHScroll(wParam, pos, control);
2704
2705 return;
2706 }
2707 }
2708 else {
2709 wxScrollEvent event;
2710 event.SetPosition(pos);
2711 event.SetOrientation(wxHORIZONTAL);
2712 event.m_eventObject = this;
2713
2714 switch ( wParam )
2715 {
2716 case SB_TOP:
2717 event.m_eventType = wxEVT_SCROLL_TOP;
2718 break;
2719
2720 case SB_BOTTOM:
2721 event.m_eventType = wxEVT_SCROLL_BOTTOM;
2722 break;
2723
2724 case SB_LINEUP:
2725 event.m_eventType = wxEVT_SCROLL_LINEUP;
2726 break;
2727
2728 case SB_LINEDOWN:
2729 event.m_eventType = wxEVT_SCROLL_LINEDOWN;
2730 break;
2731
2732 case SB_PAGEUP:
2733 event.m_eventType = wxEVT_SCROLL_PAGEUP;
2734 break;
2735
2736 case SB_PAGEDOWN:
2737 event.m_eventType = wxEVT_SCROLL_PAGEDOWN;
2738 break;
2739
2740 case SB_THUMBTRACK:
2741 case SB_THUMBPOSITION:
2742 event.m_eventType = wxEVT_SCROLL_THUMBTRACK;
2743 break;
2744
2745 default:
2746 return;
2747 }
2748
2749 if ( GetEventHandler()->ProcessEvent(event) )
2750 return;
2751 }
2752
2753 // call the default WM_HSCROLL handler: it's non trivial in some common
2754 // controls (up-down control for example)
2755 Default();
2756 }
2757
2758 void wxWindow::MSWOnShow(bool show, int status)
2759 {
2760 wxShowEvent event(GetId(), show);
2761 event.m_eventObject = this;
2762 GetEventHandler()->ProcessEvent(event);
2763 }
2764
2765 bool wxWindow::MSWOnInitDialog(WXHWND WXUNUSED(hWndFocus))
2766 {
2767 wxInitDialogEvent event(GetId());
2768 event.m_eventObject = this;
2769 GetEventHandler()->ProcessEvent(event);
2770 return TRUE;
2771 }
2772
2773 void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
2774 {
2775 TEXTMETRIC tm;
2776 HDC dc = ::GetDC((HWND) wnd);
2777 HFONT fnt =0;
2778 HFONT was = 0;
2779 if ( the_font )
2780 {
2781 // the_font->UseResource();
2782 // the_font->RealizeResource();
2783 fnt = (HFONT)the_font->GetResourceHandle();
2784 if ( fnt )
2785 was = (HFONT) SelectObject(dc,fnt) ;
2786 }
2787 GetTextMetrics(dc, &tm);
2788 if ( the_font && fnt && was )
2789 {
2790 SelectObject(dc,was) ;
2791 }
2792 ReleaseDC((HWND)wnd, dc);
2793 *x = tm.tmAveCharWidth;
2794 *y = tm.tmHeight + tm.tmExternalLeading;
2795
2796 // if ( the_font )
2797 // the_font->ReleaseResource();
2798 }
2799
2800 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
2801 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
2802 int wxCharCodeMSWToWX(int keySym)
2803 {
2804 int id = 0;
2805 switch (keySym)
2806 {
2807 case VK_CANCEL: id = WXK_CANCEL; break;
2808 case VK_BACK: id = WXK_BACK; break;
2809 case VK_TAB: id = WXK_TAB; break;
2810 case VK_CLEAR: id = WXK_CLEAR; break;
2811 case VK_RETURN: id = WXK_RETURN; break;
2812 case VK_SHIFT: id = WXK_SHIFT; break;
2813 case VK_CONTROL: id = WXK_CONTROL; break;
2814 case VK_MENU : id = WXK_MENU; break;
2815 case VK_PAUSE: id = WXK_PAUSE; break;
2816 case VK_SPACE: id = WXK_SPACE; break;
2817 case VK_ESCAPE: id = WXK_ESCAPE; break;
2818 case VK_PRIOR: id = WXK_PRIOR; break;
2819 case VK_NEXT : id = WXK_NEXT; break;
2820 case VK_END: id = WXK_END; break;
2821 case VK_HOME : id = WXK_HOME; break;
2822 case VK_LEFT : id = WXK_LEFT; break;
2823 case VK_UP: id = WXK_UP; break;
2824 case VK_RIGHT: id = WXK_RIGHT; break;
2825 case VK_DOWN : id = WXK_DOWN; break;
2826 case VK_SELECT: id = WXK_SELECT; break;
2827 case VK_PRINT: id = WXK_PRINT; break;
2828 case VK_EXECUTE: id = WXK_EXECUTE; break;
2829 case VK_INSERT: id = WXK_INSERT; break;
2830 case VK_DELETE: id = WXK_DELETE; break;
2831 case VK_HELP : id = WXK_HELP; break;
2832 case VK_NUMPAD0: id = WXK_NUMPAD0; break;
2833 case VK_NUMPAD1: id = WXK_NUMPAD1; break;
2834 case VK_NUMPAD2: id = WXK_NUMPAD2; break;
2835 case VK_NUMPAD3: id = WXK_NUMPAD3; break;
2836 case VK_NUMPAD4: id = WXK_NUMPAD4; break;
2837 case VK_NUMPAD5: id = WXK_NUMPAD5; break;
2838 case VK_NUMPAD6: id = WXK_NUMPAD6; break;
2839 case VK_NUMPAD7: id = WXK_NUMPAD7; break;
2840 case VK_NUMPAD8: id = WXK_NUMPAD8; break;
2841 case VK_NUMPAD9: id = WXK_NUMPAD9; break;
2842 case VK_MULTIPLY: id = WXK_MULTIPLY; break;
2843 case VK_ADD: id = WXK_ADD; break;
2844 case VK_SUBTRACT: id = WXK_SUBTRACT; break;
2845 case VK_DECIMAL: id = WXK_DECIMAL; break;
2846 case VK_DIVIDE: id = WXK_DIVIDE; break;
2847 case VK_F1: id = WXK_F1; break;
2848 case VK_F2: id = WXK_F2; break;
2849 case VK_F3: id = WXK_F3; break;
2850 case VK_F4: id = WXK_F4; break;
2851 case VK_F5: id = WXK_F5; break;
2852 case VK_F6: id = WXK_F6; break;
2853 case VK_F7: id = WXK_F7; break;
2854 case VK_F8: id = WXK_F8; break;
2855 case VK_F9: id = WXK_F9; break;
2856 case VK_F10: id = WXK_F10; break;
2857 case VK_F11: id = WXK_F11; break;
2858 case VK_F12: id = WXK_F12; break;
2859 case VK_F13: id = WXK_F13; break;
2860 case VK_F14: id = WXK_F14; break;
2861 case VK_F15: id = WXK_F15; break;
2862 case VK_F16: id = WXK_F16; break;
2863 case VK_F17: id = WXK_F17; break;
2864 case VK_F18: id = WXK_F18; break;
2865 case VK_F19: id = WXK_F19; break;
2866 case VK_F20: id = WXK_F20; break;
2867 case VK_F21: id = WXK_F21; break;
2868 case VK_F22: id = WXK_F22; break;
2869 case VK_F23: id = WXK_F23; break;
2870 case VK_F24: id = WXK_F24; break;
2871 case VK_NUMLOCK: id = WXK_NUMLOCK; break;
2872 case VK_SCROLL: id = WXK_SCROLL; break;
2873 default:
2874 {
2875 return 0;
2876 }
2877 }
2878 return id;
2879 }
2880
2881 int wxCharCodeWXToMSW(int id, bool *isVirtual)
2882 {
2883 *isVirtual = TRUE;
2884 int keySym = 0;
2885 switch (id)
2886 {
2887 case WXK_CANCEL: keySym = VK_CANCEL; break;
2888 case WXK_CLEAR: keySym = VK_CLEAR; break;
2889 case WXK_SHIFT: keySym = VK_SHIFT; break;
2890 case WXK_CONTROL: keySym = VK_CONTROL; break;
2891 case WXK_MENU : keySym = VK_MENU; break;
2892 case WXK_PAUSE: keySym = VK_PAUSE; break;
2893 case WXK_PRIOR: keySym = VK_PRIOR; break;
2894 case WXK_NEXT : keySym = VK_NEXT; break;
2895 case WXK_END: keySym = VK_END; break;
2896 case WXK_HOME : keySym = VK_HOME; break;
2897 case WXK_LEFT : keySym = VK_LEFT; break;
2898 case WXK_UP: keySym = VK_UP; break;
2899 case WXK_RIGHT: keySym = VK_RIGHT; break;
2900 case WXK_DOWN : keySym = VK_DOWN; break;
2901 case WXK_SELECT: keySym = VK_SELECT; break;
2902 case WXK_PRINT: keySym = VK_PRINT; break;
2903 case WXK_EXECUTE: keySym = VK_EXECUTE; break;
2904 case WXK_INSERT: keySym = VK_INSERT; break;
2905 case WXK_DELETE: keySym = VK_DELETE; break;
2906 case WXK_HELP : keySym = VK_HELP; break;
2907 case WXK_NUMPAD0: keySym = VK_NUMPAD0; break;
2908 case WXK_NUMPAD1: keySym = VK_NUMPAD1; break;
2909 case WXK_NUMPAD2: keySym = VK_NUMPAD2; break;
2910 case WXK_NUMPAD3: keySym = VK_NUMPAD3; break;
2911 case WXK_NUMPAD4: keySym = VK_NUMPAD4; break;
2912 case WXK_NUMPAD5: keySym = VK_NUMPAD5; break;
2913 case WXK_NUMPAD6: keySym = VK_NUMPAD6; break;
2914 case WXK_NUMPAD7: keySym = VK_NUMPAD7; break;
2915 case WXK_NUMPAD8: keySym = VK_NUMPAD8; break;
2916 case WXK_NUMPAD9: keySym = VK_NUMPAD9; break;
2917 case WXK_MULTIPLY: keySym = VK_MULTIPLY; break;
2918 case WXK_ADD: keySym = VK_ADD; break;
2919 case WXK_SUBTRACT: keySym = VK_SUBTRACT; break;
2920 case WXK_DECIMAL: keySym = VK_DECIMAL; break;
2921 case WXK_DIVIDE: keySym = VK_DIVIDE; break;
2922 case WXK_F1: keySym = VK_F1; break;
2923 case WXK_F2: keySym = VK_F2; break;
2924 case WXK_F3: keySym = VK_F3; break;
2925 case WXK_F4: keySym = VK_F4; break;
2926 case WXK_F5: keySym = VK_F5; break;
2927 case WXK_F6: keySym = VK_F6; break;
2928 case WXK_F7: keySym = VK_F7; break;
2929 case WXK_F8: keySym = VK_F8; break;
2930 case WXK_F9: keySym = VK_F9; break;
2931 case WXK_F10: keySym = VK_F10; break;
2932 case WXK_F11: keySym = VK_F11; break;
2933 case WXK_F12: keySym = VK_F12; break;
2934 case WXK_F13: keySym = VK_F13; break;
2935 case WXK_F14: keySym = VK_F14; break;
2936 case WXK_F15: keySym = VK_F15; break;
2937 case WXK_F16: keySym = VK_F16; break;
2938 case WXK_F17: keySym = VK_F17; break;
2939 case WXK_F18: keySym = VK_F18; break;
2940 case WXK_F19: keySym = VK_F19; break;
2941 case WXK_F20: keySym = VK_F20; break;
2942 case WXK_F21: keySym = VK_F21; break;
2943 case WXK_F22: keySym = VK_F22; break;
2944 case WXK_F23: keySym = VK_F23; break;
2945 case WXK_F24: keySym = VK_F24; break;
2946 case WXK_NUMLOCK: keySym = VK_NUMLOCK; break;
2947 case WXK_SCROLL: keySym = VK_SCROLL; break;
2948 default:
2949 {
2950 *isVirtual = FALSE;
2951 keySym = id;
2952 break;
2953 }
2954 }
2955 return keySym;
2956 }
2957
2958 // Caret manipulation
2959 void wxWindow::CreateCaret(int w, int h)
2960 {
2961 m_caretWidth = w;
2962 m_caretHeight = h;
2963 m_caretEnabled = TRUE;
2964 }
2965
2966 void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
2967 {
2968 // Not implemented
2969 }
2970
2971 void wxWindow::ShowCaret(bool show)
2972 {
2973 if ( m_caretEnabled )
2974 {
2975 if ( show )
2976 ::ShowCaret((HWND) GetHWND());
2977 else
2978 ::HideCaret((HWND) GetHWND());
2979 m_caretShown = show;
2980 }
2981 }
2982
2983 void wxWindow::DestroyCaret()
2984 {
2985 m_caretEnabled = FALSE;
2986 }
2987
2988 void wxWindow::SetCaretPos(int x, int y)
2989 {
2990 ::SetCaretPos(x, y);
2991 }
2992
2993 void wxWindow::GetCaretPos(int *x, int *y) const
2994 {
2995 POINT point;
2996 ::GetCaretPos(&point);
2997 *x = point.x;
2998 *y = point.y;
2999 }
3000
3001 wxWindow *wxGetActiveWindow()
3002 {
3003 HWND hWnd = GetActiveWindow();
3004 if ( hWnd != 0 )
3005 {
3006 return wxFindWinFromHandle((WXHWND) hWnd);
3007 }
3008 return NULL;
3009 }
3010
3011 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
3012 // in active frames and dialogs, regardless of where the focus is.
3013 static HHOOK wxTheKeyboardHook = 0;
3014 static FARPROC wxTheKeyboardHookProc = 0;
3015 int APIENTRY _EXPORT
3016 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam);
3017
3018 void wxSetKeyboardHook(bool doIt)
3019 {
3020 if ( doIt )
3021 {
3022 wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
3023 wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
3024 #if defined(__WIN32__) && !defined(__TWIN32__)
3025 GetCurrentThreadId());
3026 // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
3027 #else
3028 GetCurrentTask());
3029 #endif
3030 }
3031 else
3032 {
3033 UnhookWindowsHookEx(wxTheKeyboardHook);
3034 FreeProcInstance(wxTheKeyboardHookProc);
3035 }
3036 }
3037
3038 int APIENTRY _EXPORT
3039 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
3040 {
3041 DWORD hiWord = HIWORD(lParam);
3042 if ( nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0) )
3043 {
3044 int id;
3045 if ( (id = wxCharCodeMSWToWX(wParam)) != 0 )
3046 {
3047 wxKeyEvent event(wxEVT_CHAR_HOOK);
3048 if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
3049 event.m_altDown = TRUE;
3050
3051 event.m_eventObject = NULL;
3052 event.m_keyCode = id;
3053 /* begin Albert's fix for control and shift key 26.5 */
3054 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
3055 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
3056 /* end Albert's fix for control and shift key 26.5 */
3057 event.SetTimestamp(wxApp::sm_lastMessageTime);
3058
3059 wxWindow *win = wxGetActiveWindow();
3060 if ( win )
3061 {
3062 if ( win->GetEventHandler()->ProcessEvent(event) )
3063 return 1;
3064 }
3065 else
3066 {
3067 if ( wxTheApp && wxTheApp->ProcessEvent(event) )
3068 return 1;
3069 }
3070 }
3071 }
3072 return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
3073 }
3074
3075 void wxWindow::WarpPointer (int x_pos, int y_pos)
3076 {
3077 // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
3078 // pixel coordinates, relatives to the canvas -- So, we first need to
3079 // substract origin of the window, then convert to screen position
3080
3081 int x = x_pos; int y = y_pos;
3082 RECT rect;
3083 GetWindowRect ((HWND) GetHWND(), &rect);
3084
3085 x += rect.left;
3086 y += rect.top;
3087
3088 SetCursorPos (x, y);
3089 }
3090
3091 void wxWindow::MSWDeviceToLogical (float *x, float *y) const
3092 {
3093 }
3094
3095 bool wxWindow::MSWOnEraseBkgnd (WXHDC pDC)
3096 {
3097 wxDC dc ;
3098
3099 dc.SetHDC(pDC);
3100 dc.SetWindow(this);
3101 dc.BeginDrawing();
3102
3103 wxEraseEvent event(m_windowId, &dc);
3104 event.m_eventObject = this;
3105 if ( !GetEventHandler()->ProcessEvent(event) )
3106 {
3107 dc.EndDrawing();
3108 dc.SelectOldObjects(pDC);
3109 return FALSE;
3110 }
3111 else
3112 {
3113 dc.EndDrawing();
3114 dc.SelectOldObjects(pDC);
3115 }
3116
3117 dc.SetHDC((WXHDC) NULL);
3118 return TRUE;
3119 }
3120
3121 void wxWindow::OnEraseBackground(wxEraseEvent& event)
3122 {
3123 if ( !GetHWND() )
3124 return;
3125
3126 RECT rect;
3127 ::GetClientRect((HWND) GetHWND(), &rect);
3128
3129 COLORREF ref = PALETTERGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()) ;
3130 HBRUSH hBrush = ::CreateSolidBrush(ref);
3131 int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
3132
3133 // ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
3134 ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
3135 ::DeleteObject(hBrush);
3136 ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
3137 /*
3138 // Less efficient version (and doesn't account for scrolling)
3139 int w, h;
3140 GetClientSize(& w, & h);
3141 wxBrush *brush = wxTheBrushList->FindOrCreateBrush(& GetBackgroundColour(), wxSOLID);
3142 event.GetDC()->SetBrush(brush);
3143 event.GetDC()->SetPen(wxTRANSPARENT_PEN);
3144
3145 event.GetDC()->DrawRectangle(0, 0, w+1, h+1);
3146 */
3147 }
3148
3149 #if WXWIN_COMPATIBILITY
3150 void wxWindow::SetScrollRange(int orient, int range, bool refresh)
3151 {
3152 #if defined(__WIN95__)
3153
3154 int range1 = range;
3155
3156 // Try to adjust the range to cope with page size > 1
3157 // - a Windows API quirk
3158 int pageSize = GetScrollPage(orient);
3159 if ( pageSize > 1 && range > 0)
3160 {
3161 range1 += (pageSize - 1);
3162 }
3163
3164 SCROLLINFO info;
3165 int dir;
3166
3167 if ( orient == wxHORIZONTAL ) {
3168 dir = SB_HORZ;
3169 } else {
3170 dir = SB_VERT;
3171 }
3172
3173 info.cbSize = sizeof(SCROLLINFO);
3174 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3175 info.nMin = 0;
3176 info.nMax = range1;
3177 info.nPos = 0;
3178 info.fMask = SIF_RANGE | SIF_PAGE;
3179
3180 HWND hWnd = (HWND) GetHWND();
3181 if ( hWnd )
3182 ::SetScrollInfo(hWnd, dir, &info, refresh);
3183 #else
3184 int wOrient ;
3185 if ( orient == wxHORIZONTAL )
3186 wOrient = SB_HORZ;
3187 else
3188 wOrient = SB_VERT;
3189
3190 HWND hWnd = (HWND) GetHWND();
3191 if ( hWnd )
3192 ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
3193 #endif
3194 }
3195
3196 void wxWindow::SetScrollPage(int orient, int page, bool refresh)
3197 {
3198 #if defined(__WIN95__)
3199 SCROLLINFO info;
3200 int dir;
3201
3202 if ( orient == wxHORIZONTAL ) {
3203 dir = SB_HORZ;
3204 m_xThumbSize = page;
3205 } else {
3206 dir = SB_VERT;
3207 m_yThumbSize = page;
3208 }
3209
3210 info.cbSize = sizeof(SCROLLINFO);
3211 info.nPage = page;
3212 info.nMin = 0;
3213 info.fMask = SIF_PAGE ;
3214
3215 HWND hWnd = (HWND) GetHWND();
3216 if ( hWnd )
3217 ::SetScrollInfo(hWnd, dir, &info, refresh);
3218 #else
3219 if ( orient == wxHORIZONTAL )
3220 m_xThumbSize = page;
3221 else
3222 m_yThumbSize = page;
3223 #endif
3224 }
3225
3226 int wxWindow::OldGetScrollRange(int orient) const
3227 {
3228 int wOrient ;
3229 if ( orient == wxHORIZONTAL )
3230 wOrient = SB_HORZ;
3231 else
3232 wOrient = SB_VERT;
3233
3234 #if __WATCOMC__ && defined(__WINDOWS_386__)
3235 short minPos, maxPos;
3236 #else
3237 int minPos, maxPos;
3238 #endif
3239 HWND hWnd = (HWND) GetHWND();
3240 if ( hWnd )
3241 {
3242 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3243 #if defined(__WIN95__)
3244 // Try to adjust the range to cope with page size > 1
3245 // - a Windows API quirk
3246 int pageSize = GetScrollPage(orient);
3247 if ( pageSize > 1 )
3248 {
3249 maxPos -= (pageSize - 1);
3250 }
3251 #endif
3252 return maxPos;
3253 }
3254 else
3255 return 0;
3256 }
3257
3258 int wxWindow::GetScrollPage(int orient) const
3259 {
3260 if ( orient == wxHORIZONTAL )
3261 return m_xThumbSize;
3262 else
3263 return m_yThumbSize;
3264 }
3265 #endif
3266
3267 int wxWindow::GetScrollPos(int orient) const
3268 {
3269 int wOrient ;
3270 if ( orient == wxHORIZONTAL )
3271 wOrient = SB_HORZ;
3272 else
3273 wOrient = SB_VERT;
3274 HWND hWnd = (HWND) GetHWND();
3275 if ( hWnd )
3276 {
3277 return ::GetScrollPos(hWnd, wOrient);
3278 }
3279 else
3280 return 0;
3281 }
3282
3283 // This now returns the whole range, not just the number
3284 // of positions that we can scroll.
3285 int wxWindow::GetScrollRange(int orient) const
3286 {
3287 int wOrient ;
3288 if ( orient == wxHORIZONTAL )
3289 wOrient = SB_HORZ;
3290 else
3291 wOrient = SB_VERT;
3292
3293 #if __WATCOMC__ && defined(__WINDOWS_386__)
3294 short minPos, maxPos;
3295 #else
3296 int minPos, maxPos;
3297 #endif
3298 HWND hWnd = (HWND) GetHWND();
3299 if ( hWnd )
3300 {
3301 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3302 #if defined(__WIN95__)
3303 // Try to adjust the range to cope with page size > 1
3304 // - a Windows API quirk
3305 int pageSize = GetScrollThumb(orient);
3306 if ( pageSize > 1 )
3307 {
3308 maxPos -= (pageSize - 1);
3309 }
3310 // October 10th: new range concept.
3311 maxPos += pageSize;
3312 #endif
3313
3314 return maxPos;
3315 }
3316 else
3317 return 0;
3318 }
3319
3320 int wxWindow::GetScrollThumb(int orient) const
3321 {
3322 if ( orient == wxHORIZONTAL )
3323 return m_xThumbSize;
3324 else
3325 return m_yThumbSize;
3326 }
3327
3328 void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
3329 {
3330 #if defined(__WIN95__)
3331 SCROLLINFO info;
3332 int dir;
3333
3334 if ( orient == wxHORIZONTAL ) {
3335 dir = SB_HORZ;
3336 } else {
3337 dir = SB_VERT;
3338 }
3339
3340 info.cbSize = sizeof(SCROLLINFO);
3341 info.nPage = 0;
3342 info.nMin = 0;
3343 info.nPos = pos;
3344 info.fMask = SIF_POS ;
3345
3346 HWND hWnd = (HWND) GetHWND();
3347 if ( hWnd )
3348 ::SetScrollInfo(hWnd, dir, &info, refresh);
3349 #else
3350 int wOrient ;
3351 if ( orient == wxHORIZONTAL )
3352 wOrient = SB_HORZ;
3353 else
3354 wOrient = SB_VERT;
3355
3356 HWND hWnd = (HWND) GetHWND();
3357 if ( hWnd )
3358 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3359 #endif
3360 }
3361
3362 // New function that will replace some of the above.
3363 void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
3364 int range, bool refresh)
3365 {
3366 /*
3367 SetScrollPage(orient, thumbVisible, FALSE);
3368
3369 int oldRange = range - thumbVisible ;
3370 SetScrollRange(orient, oldRange, FALSE);
3371
3372 SetScrollPos(orient, pos, refresh);
3373 */
3374 #if defined(__WIN95__)
3375 int oldRange = range - thumbVisible ;
3376
3377 int range1 = oldRange;
3378
3379 // Try to adjust the range to cope with page size > 1
3380 // - a Windows API quirk
3381 int pageSize = thumbVisible;
3382 if ( pageSize > 1 && range > 0)
3383 {
3384 range1 += (pageSize - 1);
3385 }
3386
3387 SCROLLINFO info;
3388 int dir;
3389
3390 if ( orient == wxHORIZONTAL ) {
3391 dir = SB_HORZ;
3392 } else {
3393 dir = SB_VERT;
3394 }
3395
3396 info.cbSize = sizeof(SCROLLINFO);
3397 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3398 info.nMin = 0;
3399 info.nMax = range1;
3400 info.nPos = pos;
3401 info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
3402
3403 HWND hWnd = (HWND) GetHWND();
3404 if ( hWnd )
3405 ::SetScrollInfo(hWnd, dir, &info, refresh);
3406 #else
3407 int wOrient ;
3408 if ( orient == wxHORIZONTAL )
3409 wOrient = SB_HORZ;
3410 else
3411 wOrient = SB_VERT;
3412
3413 HWND hWnd = (HWND) GetHWND();
3414 if ( hWnd )
3415 {
3416 ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
3417 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3418 }
3419 #endif
3420 if ( orient == wxHORIZONTAL ) {
3421 m_xThumbSize = thumbVisible;
3422 } else {
3423 m_yThumbSize = thumbVisible;
3424 }
3425 }
3426
3427 void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
3428 {
3429 RECT rect2;
3430 if ( rect )
3431 {
3432 rect2.left = rect->x;
3433 rect2.top = rect->y;
3434 rect2.right = rect->x + rect->width;
3435 rect2.bottom = rect->y + rect->height;
3436 }
3437
3438 if ( rect )
3439 ::ScrollWindow((HWND) GetHWND(), dx, dy, &rect2, NULL);
3440 else
3441 ::ScrollWindow((HWND) GetHWND(), dx, dy, NULL, NULL);
3442 }
3443
3444 bool wxWindow::SetFont(const wxFont& font)
3445 {
3446 if ( !wxWindowBase::SetFont(font) )
3447 {
3448 // nothing to do
3449 return FALSE;
3450 }
3451
3452 HWND hWnd = (HWND) GetHWND();
3453 if ( hWnd != 0 )
3454 {
3455 WXHANDLE hFont = m_font.GetResourceHandle();
3456
3457 wxASSERT_MSG( hFont, _T("should have valid font") );
3458
3459 ::SendMessage(hWnd, WM_SETFONT, (WPARAM)hFont, TRUE);
3460 }
3461
3462 return TRUE;
3463 }
3464
3465 void wxWindow::SubclassWin(WXHWND hWnd)
3466 {
3467 wxASSERT_MSG( !m_oldWndProc, "subclassing window twice?" );
3468
3469 wxAssociateWinWithHandle((HWND)hWnd, this);
3470
3471 m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC);
3472 SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc);
3473 }
3474
3475 void wxWindow::UnsubclassWin()
3476 {
3477 wxRemoveHandleAssociation(this);
3478
3479 // Restore old Window proc
3480 if ( (HWND) GetHWND() )
3481 {
3482 FARPROC farProc = (FARPROC) GetWindowLong((HWND) GetHWND(), GWL_WNDPROC);
3483 if ( (m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc) )
3484 {
3485 SetWindowLong((HWND) GetHWND(), GWL_WNDPROC, (LONG) m_oldWndProc);
3486 m_oldWndProc = 0;
3487 }
3488 }
3489 }
3490
3491 // Make a Windows extended style from the given wxWindows window style
3492 WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders)
3493 {
3494 WXDWORD exStyle = 0;
3495 if ( style & wxTRANSPARENT_WINDOW )
3496 exStyle |= WS_EX_TRANSPARENT ;
3497
3498 if ( !eliminateBorders )
3499 {
3500 if ( style & wxSUNKEN_BORDER )
3501 exStyle |= WS_EX_CLIENTEDGE ;
3502 if ( style & wxDOUBLE_BORDER )
3503 exStyle |= WS_EX_DLGMODALFRAME ;
3504 #if defined(__WIN95__)
3505 if ( style & wxRAISED_BORDER )
3506 exStyle |= WS_EX_WINDOWEDGE ;
3507 if ( style & wxSTATIC_BORDER )
3508 exStyle |= WS_EX_STATICEDGE ;
3509 #endif
3510 }
3511 return exStyle;
3512 }
3513
3514 // Determines whether native 3D effects or CTL3D should be used,
3515 // applying a default border style if required, and returning an extended
3516 // style to pass to CreateWindowEx.
3517 WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
3518 {
3519 // If matches certain criteria, then assume no 3D effects
3520 // unless specifically requested (dealt with in MakeExtendedStyle)
3521 if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
3522 {
3523 *want3D = FALSE;
3524 return MakeExtendedStyle(m_windowStyle, FALSE);
3525 }
3526
3527 // Determine whether we should be using 3D effects or not.
3528 bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
3529
3530 // 1) App can specify global 3D effects
3531 *want3D = wxTheApp->GetAuto3D();
3532
3533 // 2) If the parent is being drawn with user colours, or simple border specified,
3534 // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
3535 if ( GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER) )
3536 *want3D = FALSE;
3537
3538 // 3) Control can override this global setting by defining
3539 // a border style, e.g. wxSUNKEN_BORDER
3540 if ( m_windowStyle & wxSUNKEN_BORDER )
3541 *want3D = TRUE;
3542
3543 // 4) If it's a special border, CTL3D can't cope so we want a native border
3544 if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
3545 (m_windowStyle & wxSTATIC_BORDER) )
3546 {
3547 *want3D = TRUE;
3548 nativeBorder = TRUE;
3549 }
3550
3551 // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
3552 // effects from extended style
3553 #if wxUSE_CTL3D
3554 if ( *want3D )
3555 nativeBorder = FALSE;
3556 #endif
3557
3558 DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
3559
3560 // If we want 3D, but haven't specified a border here,
3561 // apply the default border style specified.
3562 // TODO what about non-Win95 WIN32? Does it have borders?
3563 #if defined(__WIN95__) && !wxUSE_CTL3D
3564 if ( defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
3565 (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
3566 exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
3567 #endif
3568
3569 return exStyle;
3570 }
3571
3572 void wxWindow::OnChar(wxKeyEvent& event)
3573 {
3574 event.Skip();
3575 }
3576
3577 void wxWindow::OnKeyDown(wxKeyEvent& event)
3578 {
3579 Default();
3580 }
3581
3582 void wxWindow::OnKeyUp(wxKeyEvent& event)
3583 {
3584 Default();
3585 }
3586
3587 void wxWindow::OnPaint(wxPaintEvent& event)
3588 {
3589 Default();
3590 }
3591
3592 // Get the window with the focus
3593 wxWindow *wxWindowBase::FindFocus()
3594 {
3595 HWND hWnd = ::GetFocus();
3596 if ( hWnd )
3597 {
3598 return wxFindWinFromHandle((WXHWND) hWnd);
3599 }
3600 return NULL;
3601 }
3602
3603 // If nothing defined for this, try the parent.
3604 // E.g. we may be a button loaded from a resource, with no callback function
3605 // defined.
3606 void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
3607 {
3608 if ( GetEventHandler()->ProcessEvent(event) )
3609 return;
3610 if ( m_parent )
3611 m_parent->GetEventHandler()->OnCommand(win, event);
3612 }
3613
3614 wxObject* wxWindow::GetChild(int number) const
3615 {
3616 // Return a pointer to the Nth object in the Panel
3617 // if ( !GetChildren() )
3618 // return(NULL) ;
3619 wxNode *node = GetChildren().First();
3620 int n = number;
3621 while (node && n--)
3622 node = node->Next() ;
3623 if ( node )
3624 {
3625 wxObject *obj = (wxObject *)node->Data();
3626 return(obj) ;
3627 }
3628 else
3629 return NULL ;
3630 }
3631
3632 void wxWindow::OnDefaultAction(wxControl *initiatingItem)
3633 {
3634 /* This is obsolete now; if we wish to intercept listbox double-clicks,
3635 * we explicitly intercept the wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
3636 * event.
3637
3638 if ( initiatingItem->IsKindOf(CLASSINFO(wxListBox)) )
3639 {
3640 wxListBox *lbox = (wxListBox *)initiatingItem;
3641 wxCommandEvent event(wxEVT_COMMAND_LEFT_DCLICK);
3642 event.m_commandInt = -1;
3643 if ( (lbox->GetWindowStyleFlag() & wxLB_MULTIPLE) == 0 )
3644 {
3645 event.m_commandString = copystring(lbox->GetStringSelection());
3646 event.m_commandInt = lbox->GetSelection();
3647 event.m_clientData = lbox->wxListBox::GetClientData(event.m_commandInt);
3648 }
3649 event.m_eventObject = lbox;
3650
3651 lbox->ProcessCommand(event);
3652
3653 if ( event.m_commandString )
3654 delete[] event.m_commandString;
3655 return;
3656 }
3657
3658 wxButton *but = GetDefaultItem();
3659 if ( but )
3660 {
3661 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED);
3662 event.SetEventObject(but);
3663 but->Command(event);
3664 }
3665 */
3666 }
3667
3668 void wxWindow::Clear()
3669 {
3670 wxClientDC dc(this);
3671 wxBrush brush(GetBackgroundColour(), wxSOLID);
3672 dc.SetBackground(brush);
3673 dc.Clear();
3674 }
3675
3676 /* TODO
3677 // Default input behaviour for a scrolling canvas should be to scroll
3678 // according to the cursor keys pressed
3679 void wxWindow::OnChar(wxKeyEvent& event)
3680 {
3681 int x_page = 0;
3682 int y_page = 0;
3683 int start_x = 0;
3684 int start_y = 0;
3685 // Bugfix Begin
3686 int v_width = 0;
3687 int v_height = 0;
3688 int y_pages = 0;
3689 // Bugfix End
3690
3691 GetScrollUnitsPerPage(&x_page, &y_page);
3692 // Bugfix Begin
3693 GetVirtualSize(&v_width,&v_height);
3694 // Bugfix End
3695 ViewStart(&start_x, &start_y);
3696 // Bugfix begin
3697 if ( vert_units )
3698 y_pages = (int)(v_height/vert_units) - y_page;
3699
3700 #ifdef __WXMSW__
3701 int y = 0;
3702 #else
3703 int y = y_page-1;
3704 #endif
3705 // Bugfix End
3706 switch (event.keyCode)
3707 {
3708 case WXK_PRIOR:
3709 {
3710 // BugFix Begin
3711 if ( y_page > 0 )
3712 {
3713 if ( start_y - y_page > 0 )
3714 Scroll(start_x, start_y - y_page);
3715 else
3716 Scroll(start_x, 0);
3717 }
3718 // Bugfix End
3719 break;
3720 }
3721 case WXK_NEXT:
3722 {
3723 // Bugfix Begin
3724 if ( (y_page > 0) && (start_y <= y_pages-y-1) )
3725 {
3726 if ( y_pages + y < start_y + y_page )
3727 Scroll(start_x, y_pages + y);
3728 else
3729 Scroll(start_x, start_y + y_page);
3730 }
3731 // Bugfix End
3732 break;
3733 }
3734 case WXK_UP:
3735 {
3736 if ( (y_page > 0) && (start_y >= 1) )
3737 Scroll(start_x, start_y - 1);
3738 break;
3739 }
3740 case WXK_DOWN:
3741 {
3742 // Bugfix Begin
3743 if ( (y_page > 0) && (start_y <= y_pages-y-1) )
3744 // Bugfix End
3745 {
3746 Scroll(start_x, start_y + 1);
3747 }
3748 break;
3749 }
3750 case WXK_LEFT:
3751 {
3752 if ( (x_page > 0) && (start_x >= 1) )
3753 Scroll(start_x - 1, start_y);
3754 break;
3755 }
3756 case WXK_RIGHT:
3757 {
3758 if ( x_page > 0 )
3759 Scroll(start_x + 1, start_y);
3760 break;
3761 }
3762 case WXK_HOME:
3763 {
3764 Scroll(0, 0);
3765 break;
3766 }
3767 // This is new
3768 case WXK_END:
3769 {
3770 Scroll(start_x, y_pages+y);
3771 break;
3772 }
3773 // end
3774 }
3775 }
3776 */
3777
3778 // Setup background and foreground colours correctly
3779 void wxWindow::SetupColours()
3780 {
3781 if ( GetParent() )
3782 SetBackgroundColour(GetParent()->GetBackgroundColour());
3783 }
3784
3785 void wxWindow::OnIdle(wxIdleEvent& event)
3786 {
3787 // Check if we need to send a LEAVE event
3788 if ( m_mouseInWindow )
3789 {
3790 POINT pt;
3791 ::GetCursorPos(&pt);
3792 if ( ::WindowFromPoint(pt) != (HWND) GetHWND() )
3793 {
3794 // Generate a LEAVE event
3795 m_mouseInWindow = FALSE;
3796
3797 int state = 0;
3798 if ( ::GetKeyState(VK_SHIFT) != 0 )
3799 state |= MK_SHIFT;
3800 if ( ::GetKeyState(VK_CONTROL) != 0 )
3801 state |= MK_CONTROL;
3802
3803 // Unfortunately the mouse button and keyboard state may have changed
3804 // by the time the OnIdle function is called, so 'state' may be
3805 // meaningless.
3806
3807 MSWOnMouseLeave(pt.x, pt.y, state);
3808 }
3809 }
3810 UpdateWindowUI();
3811 }
3812
3813 // Raise the window to the top of the Z order
3814 void wxWindow::Raise()
3815 {
3816 ::BringWindowToTop((HWND) GetHWND());
3817 }
3818
3819 // Lower the window to the bottom of the Z order
3820 void wxWindow::Lower()
3821 {
3822 ::SetWindowPos((HWND) GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
3823 }
3824
3825 long wxWindow::MSWGetDlgCode()
3826 {
3827 // default: just forward to def window proc (the msg has no parameters)
3828 return MSWDefWindowProc(WM_GETDLGCODE, 0, 0);
3829 }
3830
3831 // Set this window to be the child of 'parent'.
3832 bool wxWindow::Reparent(wxWindow *parent)
3833 {
3834 if ( !wxWindowBase::Reparent(parent) )
3835 return FALSE;
3836
3837 HWND hWndChild = (HWND)GetHWND();
3838 HWND hWndParent = (HWND)(GetParent() ? GetParent()->GetHWND() : NULL);
3839
3840 ::SetParent(hWndChild, hWndParent);
3841
3842 return TRUE;
3843 }
3844
3845 #ifdef __WXDEBUG__
3846 const char *wxGetMessageName(int message)
3847 {
3848 switch ( message ) {
3849 case 0x0000: return "WM_NULL";
3850 case 0x0001: return "WM_CREATE";
3851 case 0x0002: return "WM_DESTROY";
3852 case 0x0003: return "WM_MOVE";
3853 case 0x0005: return "WM_SIZE";
3854 case 0x0006: return "WM_ACTIVATE";
3855 case 0x0007: return "WM_SETFOCUS";
3856 case 0x0008: return "WM_KILLFOCUS";
3857 case 0x000A: return "WM_ENABLE";
3858 case 0x000B: return "WM_SETREDRAW";
3859 case 0x000C: return "WM_SETTEXT";
3860 case 0x000D: return "WM_GETTEXT";
3861 case 0x000E: return "WM_GETTEXTLENGTH";
3862 case 0x000F: return "WM_PAINT";
3863 case 0x0010: return "WM_CLOSE";
3864 case 0x0011: return "WM_QUERYENDSESSION";
3865 case 0x0012: return "WM_QUIT";
3866 case 0x0013: return "WM_QUERYOPEN";
3867 case 0x0014: return "WM_ERASEBKGND";
3868 case 0x0015: return "WM_SYSCOLORCHANGE";
3869 case 0x0016: return "WM_ENDSESSION";
3870 case 0x0017: return "WM_SYSTEMERROR";
3871 case 0x0018: return "WM_SHOWWINDOW";
3872 case 0x0019: return "WM_CTLCOLOR";
3873 case 0x001A: return "WM_WININICHANGE";
3874 case 0x001B: return "WM_DEVMODECHANGE";
3875 case 0x001C: return "WM_ACTIVATEAPP";
3876 case 0x001D: return "WM_FONTCHANGE";
3877 case 0x001E: return "WM_TIMECHANGE";
3878 case 0x001F: return "WM_CANCELMODE";
3879 case 0x0020: return "WM_SETCURSOR";
3880 case 0x0021: return "WM_MOUSEACTIVATE";
3881 case 0x0022: return "WM_CHILDACTIVATE";
3882 case 0x0023: return "WM_QUEUESYNC";
3883 case 0x0024: return "WM_GETMINMAXINFO";
3884 case 0x0026: return "WM_PAINTICON";
3885 case 0x0027: return "WM_ICONERASEBKGND";
3886 case 0x0028: return "WM_NEXTDLGCTL";
3887 case 0x002A: return "WM_SPOOLERSTATUS";
3888 case 0x002B: return "WM_DRAWITEM";
3889 case 0x002C: return "WM_MEASUREITEM";
3890 case 0x002D: return "WM_DELETEITEM";
3891 case 0x002E: return "WM_VKEYTOITEM";
3892 case 0x002F: return "WM_CHARTOITEM";
3893 case 0x0030: return "WM_SETFONT";
3894 case 0x0031: return "WM_GETFONT";
3895 case 0x0037: return "WM_QUERYDRAGICON";
3896 case 0x0039: return "WM_COMPAREITEM";
3897 case 0x0041: return "WM_COMPACTING";
3898 case 0x0044: return "WM_COMMNOTIFY";
3899 case 0x0046: return "WM_WINDOWPOSCHANGING";
3900 case 0x0047: return "WM_WINDOWPOSCHANGED";
3901 case 0x0048: return "WM_POWER";
3902
3903 #ifdef __WIN32__
3904 case 0x004A: return "WM_COPYDATA";
3905 case 0x004B: return "WM_CANCELJOURNAL";
3906 case 0x004E: return "WM_NOTIFY";
3907 case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
3908 case 0x0051: return "WM_INPUTLANGCHANGE";
3909 case 0x0052: return "WM_TCARD";
3910 case 0x0053: return "WM_HELP";
3911 case 0x0054: return "WM_USERCHANGED";
3912 case 0x0055: return "WM_NOTIFYFORMAT";
3913 case 0x007B: return "WM_CONTEXTMENU";
3914 case 0x007C: return "WM_STYLECHANGING";
3915 case 0x007D: return "WM_STYLECHANGED";
3916 case 0x007E: return "WM_DISPLAYCHANGE";
3917 case 0x007F: return "WM_GETICON";
3918 case 0x0080: return "WM_SETICON";
3919 #endif //WIN32
3920
3921 case 0x0081: return "WM_NCCREATE";
3922 case 0x0082: return "WM_NCDESTROY";
3923 case 0x0083: return "WM_NCCALCSIZE";
3924 case 0x0084: return "WM_NCHITTEST";
3925 case 0x0085: return "WM_NCPAINT";
3926 case 0x0086: return "WM_NCACTIVATE";
3927 case 0x0087: return "WM_GETDLGCODE";
3928 case 0x00A0: return "WM_NCMOUSEMOVE";
3929 case 0x00A1: return "WM_NCLBUTTONDOWN";
3930 case 0x00A2: return "WM_NCLBUTTONUP";
3931 case 0x00A3: return "WM_NCLBUTTONDBLCLK";
3932 case 0x00A4: return "WM_NCRBUTTONDOWN";
3933 case 0x00A5: return "WM_NCRBUTTONUP";
3934 case 0x00A6: return "WM_NCRBUTTONDBLCLK";
3935 case 0x00A7: return "WM_NCMBUTTONDOWN";
3936 case 0x00A8: return "WM_NCMBUTTONUP";
3937 case 0x00A9: return "WM_NCMBUTTONDBLCLK";
3938 case 0x0100: return "WM_KEYDOWN";
3939 case 0x0101: return "WM_KEYUP";
3940 case 0x0102: return "WM_CHAR";
3941 case 0x0103: return "WM_DEADCHAR";
3942 case 0x0104: return "WM_SYSKEYDOWN";
3943 case 0x0105: return "WM_SYSKEYUP";
3944 case 0x0106: return "WM_SYSCHAR";
3945 case 0x0107: return "WM_SYSDEADCHAR";
3946 case 0x0108: return "WM_KEYLAST";
3947
3948 #ifdef __WIN32__
3949 case 0x010D: return "WM_IME_STARTCOMPOSITION";
3950 case 0x010E: return "WM_IME_ENDCOMPOSITION";
3951 case 0x010F: return "WM_IME_COMPOSITION";
3952 #endif //WIN32
3953
3954 case 0x0110: return "WM_INITDIALOG";
3955 case 0x0111: return "WM_COMMAND";
3956 case 0x0112: return "WM_SYSCOMMAND";
3957 case 0x0113: return "WM_TIMER";
3958 case 0x0114: return "WM_HSCROLL";
3959 case 0x0115: return "WM_VSCROLL";
3960 case 0x0116: return "WM_INITMENU";
3961 case 0x0117: return "WM_INITMENUPOPUP";
3962 case 0x011F: return "WM_MENUSELECT";
3963 case 0x0120: return "WM_MENUCHAR";
3964 case 0x0121: return "WM_ENTERIDLE";
3965 case 0x0200: return "WM_MOUSEMOVE";
3966 case 0x0201: return "WM_LBUTTONDOWN";
3967 case 0x0202: return "WM_LBUTTONUP";
3968 case 0x0203: return "WM_LBUTTONDBLCLK";
3969 case 0x0204: return "WM_RBUTTONDOWN";
3970 case 0x0205: return "WM_RBUTTONUP";
3971 case 0x0206: return "WM_RBUTTONDBLCLK";
3972 case 0x0207: return "WM_MBUTTONDOWN";
3973 case 0x0208: return "WM_MBUTTONUP";
3974 case 0x0209: return "WM_MBUTTONDBLCLK";
3975 case 0x0210: return "WM_PARENTNOTIFY";
3976 case 0x0211: return "WM_ENTERMENULOOP";
3977 case 0x0212: return "WM_EXITMENULOOP";
3978
3979 #ifdef __WIN32__
3980 case 0x0213: return "WM_NEXTMENU";
3981 case 0x0214: return "WM_SIZING";
3982 case 0x0215: return "WM_CAPTURECHANGED";
3983 case 0x0216: return "WM_MOVING";
3984 case 0x0218: return "WM_POWERBROADCAST";
3985 case 0x0219: return "WM_DEVICECHANGE";
3986 #endif //WIN32
3987
3988 case 0x0220: return "WM_MDICREATE";
3989 case 0x0221: return "WM_MDIDESTROY";
3990 case 0x0222: return "WM_MDIACTIVATE";
3991 case 0x0223: return "WM_MDIRESTORE";
3992 case 0x0224: return "WM_MDINEXT";
3993 case 0x0225: return "WM_MDIMAXIMIZE";
3994 case 0x0226: return "WM_MDITILE";
3995 case 0x0227: return "WM_MDICASCADE";
3996 case 0x0228: return "WM_MDIICONARRANGE";
3997 case 0x0229: return "WM_MDIGETACTIVE";
3998 case 0x0230: return "WM_MDISETMENU";
3999 case 0x0233: return "WM_DROPFILES";
4000
4001 #ifdef __WIN32__
4002 case 0x0281: return "WM_IME_SETCONTEXT";
4003 case 0x0282: return "WM_IME_NOTIFY";
4004 case 0x0283: return "WM_IME_CONTROL";
4005 case 0x0284: return "WM_IME_COMPOSITIONFULL";
4006 case 0x0285: return "WM_IME_SELECT";
4007 case 0x0286: return "WM_IME_CHAR";
4008 case 0x0290: return "WM_IME_KEYDOWN";
4009 case 0x0291: return "WM_IME_KEYUP";
4010 #endif //WIN32
4011
4012 case 0x0300: return "WM_CUT";
4013 case 0x0301: return "WM_COPY";
4014 case 0x0302: return "WM_PASTE";
4015 case 0x0303: return "WM_CLEAR";
4016 case 0x0304: return "WM_UNDO";
4017 case 0x0305: return "WM_RENDERFORMAT";
4018 case 0x0306: return "WM_RENDERALLFORMATS";
4019 case 0x0307: return "WM_DESTROYCLIPBOARD";
4020 case 0x0308: return "WM_DRAWCLIPBOARD";
4021 case 0x0309: return "WM_PAINTCLIPBOARD";
4022 case 0x030A: return "WM_VSCROLLCLIPBOARD";
4023 case 0x030B: return "WM_SIZECLIPBOARD";
4024 case 0x030C: return "WM_ASKCBFORMATNAME";
4025 case 0x030D: return "WM_CHANGECBCHAIN";
4026 case 0x030E: return "WM_HSCROLLCLIPBOARD";
4027 case 0x030F: return "WM_QUERYNEWPALETTE";
4028 case 0x0310: return "WM_PALETTEISCHANGING";
4029 case 0x0311: return "WM_PALETTECHANGED";
4030
4031 #ifdef __WIN32__
4032 // common controls messages - although they're not strictly speaking
4033 // standard, it's nice to decode them nevertheless
4034
4035 // listview
4036 case 0x1000 + 0: return "LVM_GETBKCOLOR";
4037 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4038 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4039 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4040 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4041 case 0x1000 + 5: return "LVM_GETITEMA";
4042 case 0x1000 + 75: return "LVM_GETITEMW";
4043 case 0x1000 + 6: return "LVM_SETITEMA";
4044 case 0x1000 + 76: return "LVM_SETITEMW";
4045 case 0x1000 + 7: return "LVM_INSERTITEMA";
4046 case 0x1000 + 77: return "LVM_INSERTITEMW";
4047 case 0x1000 + 8: return "LVM_DELETEITEM";
4048 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
4049 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
4050 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
4051 case 0x1000 + 12: return "LVM_GETNEXTITEM";
4052 case 0x1000 + 13: return "LVM_FINDITEMA";
4053 case 0x1000 + 83: return "LVM_FINDITEMW";
4054 case 0x1000 + 14: return "LVM_GETITEMRECT";
4055 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
4056 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
4057 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
4058 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
4059 case 0x1000 + 18: return "LVM_HITTEST";
4060 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
4061 case 0x1000 + 20: return "LVM_SCROLL";
4062 case 0x1000 + 21: return "LVM_REDRAWITEMS";
4063 case 0x1000 + 22: return "LVM_ARRANGE";
4064 case 0x1000 + 23: return "LVM_EDITLABELA";
4065 case 0x1000 + 118: return "LVM_EDITLABELW";
4066 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
4067 case 0x1000 + 25: return "LVM_GETCOLUMNA";
4068 case 0x1000 + 95: return "LVM_GETCOLUMNW";
4069 case 0x1000 + 26: return "LVM_SETCOLUMNA";
4070 case 0x1000 + 96: return "LVM_SETCOLUMNW";
4071 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
4072 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
4073 case 0x1000 + 28: return "LVM_DELETECOLUMN";
4074 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
4075 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
4076 case 0x1000 + 31: return "LVM_GETHEADER";
4077 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
4078 case 0x1000 + 34: return "LVM_GETVIEWRECT";
4079 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
4080 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
4081 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
4082 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
4083 case 0x1000 + 39: return "LVM_GETTOPINDEX";
4084 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
4085 case 0x1000 + 41: return "LVM_GETORIGIN";
4086 case 0x1000 + 42: return "LVM_UPDATE";
4087 case 0x1000 + 43: return "LVM_SETITEMSTATE";
4088 case 0x1000 + 44: return "LVM_GETITEMSTATE";
4089 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
4090 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
4091 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
4092 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
4093 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
4094 case 0x1000 + 48: return "LVM_SORTITEMS";
4095 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
4096 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
4097 case 0x1000 + 51: return "LVM_GETITEMSPACING";
4098 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
4099 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
4100 case 0x1000 + 53: return "LVM_SETICONSPACING";
4101 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
4102 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
4103 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
4104 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
4105 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
4106 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
4107 case 0x1000 + 60: return "LVM_SETHOTITEM";
4108 case 0x1000 + 61: return "LVM_GETHOTITEM";
4109 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
4110 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
4111 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
4112 case 0x1000 + 65: return "LVM_SETWORKAREA";
4113
4114 // tree view
4115 case 0x1100 + 0: return "TVM_INSERTITEMA";
4116 case 0x1100 + 50: return "TVM_INSERTITEMW";
4117 case 0x1100 + 1: return "TVM_DELETEITEM";
4118 case 0x1100 + 2: return "TVM_EXPAND";
4119 case 0x1100 + 4: return "TVM_GETITEMRECT";
4120 case 0x1100 + 5: return "TVM_GETCOUNT";
4121 case 0x1100 + 6: return "TVM_GETINDENT";
4122 case 0x1100 + 7: return "TVM_SETINDENT";
4123 case 0x1100 + 8: return "TVM_GETIMAGELIST";
4124 case 0x1100 + 9: return "TVM_SETIMAGELIST";
4125 case 0x1100 + 10: return "TVM_GETNEXTITEM";
4126 case 0x1100 + 11: return "TVM_SELECTITEM";
4127 case 0x1100 + 12: return "TVM_GETITEMA";
4128 case 0x1100 + 62: return "TVM_GETITEMW";
4129 case 0x1100 + 13: return "TVM_SETITEMA";
4130 case 0x1100 + 63: return "TVM_SETITEMW";
4131 case 0x1100 + 14: return "TVM_EDITLABELA";
4132 case 0x1100 + 65: return "TVM_EDITLABELW";
4133 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
4134 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
4135 case 0x1100 + 17: return "TVM_HITTEST";
4136 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
4137 case 0x1100 + 19: return "TVM_SORTCHILDREN";
4138 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
4139 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
4140 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
4141 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
4142 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
4143 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
4144 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
4145
4146 // header
4147 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
4148 case 0x1200 + 1: return "HDM_INSERTITEMA";
4149 case 0x1200 + 10: return "HDM_INSERTITEMW";
4150 case 0x1200 + 2: return "HDM_DELETEITEM";
4151 case 0x1200 + 3: return "HDM_GETITEMA";
4152 case 0x1200 + 11: return "HDM_GETITEMW";
4153 case 0x1200 + 4: return "HDM_SETITEMA";
4154 case 0x1200 + 12: return "HDM_SETITEMW";
4155 case 0x1200 + 5: return "HDM_LAYOUT";
4156 case 0x1200 + 6: return "HDM_HITTEST";
4157 case 0x1200 + 7: return "HDM_GETITEMRECT";
4158 case 0x1200 + 8: return "HDM_SETIMAGELIST";
4159 case 0x1200 + 9: return "HDM_GETIMAGELIST";
4160 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
4161 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
4162 case 0x1200 + 17: return "HDM_GETORDERARRAY";
4163 case 0x1200 + 18: return "HDM_SETORDERARRAY";
4164 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
4165
4166 // tab control
4167 case 0x1300 + 2: return "TCM_GETIMAGELIST";
4168 case 0x1300 + 3: return "TCM_SETIMAGELIST";
4169 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
4170 case 0x1300 + 5: return "TCM_GETITEMA";
4171 case 0x1300 + 60: return "TCM_GETITEMW";
4172 case 0x1300 + 6: return "TCM_SETITEMA";
4173 case 0x1300 + 61: return "TCM_SETITEMW";
4174 case 0x1300 + 7: return "TCM_INSERTITEMA";
4175 case 0x1300 + 62: return "TCM_INSERTITEMW";
4176 case 0x1300 + 8: return "TCM_DELETEITEM";
4177 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
4178 case 0x1300 + 10: return "TCM_GETITEMRECT";
4179 case 0x1300 + 11: return "TCM_GETCURSEL";
4180 case 0x1300 + 12: return "TCM_SETCURSEL";
4181 case 0x1300 + 13: return "TCM_HITTEST";
4182 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
4183 case 0x1300 + 40: return "TCM_ADJUSTRECT";
4184 case 0x1300 + 41: return "TCM_SETITEMSIZE";
4185 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
4186 case 0x1300 + 43: return "TCM_SETPADDING";
4187 case 0x1300 + 44: return "TCM_GETROWCOUNT";
4188 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
4189 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
4190 case 0x1300 + 47: return "TCM_GETCURFOCUS";
4191 case 0x1300 + 48: return "TCM_SETCURFOCUS";
4192 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
4193 case 0x1300 + 50: return "TCM_DESELECTALL";
4194
4195 // toolbar
4196 case WM_USER+1: return "TB_ENABLEBUTTON";
4197 case WM_USER+2: return "TB_CHECKBUTTON";
4198 case WM_USER+3: return "TB_PRESSBUTTON";
4199 case WM_USER+4: return "TB_HIDEBUTTON";
4200 case WM_USER+5: return "TB_INDETERMINATE";
4201 case WM_USER+9: return "TB_ISBUTTONENABLED";
4202 case WM_USER+10: return "TB_ISBUTTONCHECKED";
4203 case WM_USER+11: return "TB_ISBUTTONPRESSED";
4204 case WM_USER+12: return "TB_ISBUTTONHIDDEN";
4205 case WM_USER+13: return "TB_ISBUTTONINDETERMINATE";
4206 case WM_USER+17: return "TB_SETSTATE";
4207 case WM_USER+18: return "TB_GETSTATE";
4208 case WM_USER+19: return "TB_ADDBITMAP";
4209 case WM_USER+20: return "TB_ADDBUTTONS";
4210 case WM_USER+21: return "TB_INSERTBUTTON";
4211 case WM_USER+22: return "TB_DELETEBUTTON";
4212 case WM_USER+23: return "TB_GETBUTTON";
4213 case WM_USER+24: return "TB_BUTTONCOUNT";
4214 case WM_USER+25: return "TB_COMMANDTOINDEX";
4215 case WM_USER+26: return "TB_SAVERESTOREA";
4216 case WM_USER+76: return "TB_SAVERESTOREW";
4217 case WM_USER+27: return "TB_CUSTOMIZE";
4218 case WM_USER+28: return "TB_ADDSTRINGA";
4219 case WM_USER+77: return "TB_ADDSTRINGW";
4220 case WM_USER+29: return "TB_GETITEMRECT";
4221 case WM_USER+30: return "TB_BUTTONSTRUCTSIZE";
4222 case WM_USER+31: return "TB_SETBUTTONSIZE";
4223 case WM_USER+32: return "TB_SETBITMAPSIZE";
4224 case WM_USER+33: return "TB_AUTOSIZE";
4225 case WM_USER+35: return "TB_GETTOOLTIPS";
4226 case WM_USER+36: return "TB_SETTOOLTIPS";
4227 case WM_USER+37: return "TB_SETPARENT";
4228 case WM_USER+39: return "TB_SETROWS";
4229 case WM_USER+40: return "TB_GETROWS";
4230 case WM_USER+42: return "TB_SETCMDID";
4231 case WM_USER+43: return "TB_CHANGEBITMAP";
4232 case WM_USER+44: return "TB_GETBITMAP";
4233 case WM_USER+45: return "TB_GETBUTTONTEXTA";
4234 case WM_USER+75: return "TB_GETBUTTONTEXTW";
4235 case WM_USER+46: return "TB_REPLACEBITMAP";
4236 case WM_USER+47: return "TB_SETINDENT";
4237 case WM_USER+48: return "TB_SETIMAGELIST";
4238 case WM_USER+49: return "TB_GETIMAGELIST";
4239 case WM_USER+50: return "TB_LOADIMAGES";
4240 case WM_USER+51: return "TB_GETRECT";
4241 case WM_USER+52: return "TB_SETHOTIMAGELIST";
4242 case WM_USER+53: return "TB_GETHOTIMAGELIST";
4243 case WM_USER+54: return "TB_SETDISABLEDIMAGELIST";
4244 case WM_USER+55: return "TB_GETDISABLEDIMAGELIST";
4245 case WM_USER+56: return "TB_SETSTYLE";
4246 case WM_USER+57: return "TB_GETSTYLE";
4247 case WM_USER+58: return "TB_GETBUTTONSIZE";
4248 case WM_USER+59: return "TB_SETBUTTONWIDTH";
4249 case WM_USER+60: return "TB_SETMAXTEXTROWS";
4250 case WM_USER+61: return "TB_GETTEXTROWS";
4251 case WM_USER+41: return "TB_GETBITMAPFLAGS";
4252
4253 #endif //WIN32
4254
4255 default:
4256 static char s_szBuf[128];
4257 sprintf(s_szBuf, "<unknown message = %d>", message);
4258 return s_szBuf;
4259 }
4260 }
4261 #endif //__WXDEBUG__