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