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