]> git.saurik.com Git - wxWidgets.git/blob - src/msw/window.cpp
239bd48bb194047d2d9dafe83d58f77f9b335c22
[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 // Ignore 'fake' events (perhaps generated as a result of a separate real event)
1940 if (m_lastMsg == 0)
1941 return 0;
1942
1943 return this->MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
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 // No message - ensure we don't try to call the default behaviour accidentally.
2448 m_lastMsg = 0;
2449 GetEventHandler()->ProcessEvent(event);
2450 }
2451
2452 void wxWindow::MSWOnMouseLeave(const int x, const int y, const WXUINT flags)
2453 {
2454 wxMouseEvent event(wxEVT_LEAVE_WINDOW);
2455
2456 event.m_x = x; event.m_y = y;
2457 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2458 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2459 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2460 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2461 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2462 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2463 event.m_eventObject = this;
2464
2465 m_lastEvent = wxEVT_LEAVE_WINDOW;
2466 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2467 // No message - ensure we don't try to call the default behaviour accidentally.
2468 m_lastMsg = 0;
2469 GetEventHandler()->ProcessEvent(event);
2470 }
2471
2472 void wxWindow::MSWOnChar(const WXWORD wParam, const WXLPARAM lParam, const bool isASCII)
2473 {
2474 int id;
2475 bool tempControlDown = FALSE;
2476 if (isASCII)
2477 {
2478 // If 1 -> 26, translate to CTRL plus a letter.
2479 id = wParam;
2480 if ((id > 0) && (id < 27))
2481 {
2482 switch (id)
2483 {
2484 case 13:
2485 {
2486 id = WXK_RETURN;
2487 break;
2488 }
2489 case 8:
2490 {
2491 id = WXK_BACK;
2492 break;
2493 }
2494 case 9:
2495 {
2496 id = WXK_TAB;
2497 break;
2498 }
2499 default:
2500 {
2501 tempControlDown = TRUE;
2502 id = id + 96;
2503 }
2504 }
2505 }
2506 }
2507 else if ((id = wxCharCodeMSWToWX(wParam)) == 0) {
2508 // it's ASCII and will be processed here only when called from
2509 // WM_CHAR (i.e. when isASCII = TRUE)
2510 id = -1;
2511 }
2512
2513 if (id != -1)
2514 {
2515 wxKeyEvent event(wxEVT_CHAR);
2516 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
2517 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
2518 if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
2519 event.m_altDown = TRUE;
2520
2521 event.m_eventObject = this;
2522 event.m_keyCode = id;
2523 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2524
2525 POINT pt ;
2526 GetCursorPos(&pt) ;
2527 RECT rect ;
2528 GetWindowRect((HWND) GetHWND(),&rect) ;
2529 pt.x -= rect.left ;
2530 pt.y -= rect.top ;
2531
2532 event.m_x = pt.x; event.m_y = pt.y;
2533
2534 #if WXWIN_COMPATIBILITY
2535 GetEventHandler()->OldOnChar(event);
2536 #else
2537 if (!GetEventHandler()->ProcessEvent(event))
2538 Default();
2539 #endif
2540 }
2541 }
2542
2543 void wxWindow::MSWOnJoyDown(const int joystick, const int x, const int y, const WXUINT flags)
2544 {
2545 int buttons = 0;
2546 int change = 0;
2547 if (flags & JOY_BUTTON1CHG)
2548 change = wxJOY_BUTTON1;
2549 if (flags & JOY_BUTTON2CHG)
2550 change = wxJOY_BUTTON2;
2551 if (flags & JOY_BUTTON3CHG)
2552 change = wxJOY_BUTTON3;
2553 if (flags & JOY_BUTTON4CHG)
2554 change = wxJOY_BUTTON4;
2555
2556 if (flags & JOY_BUTTON1)
2557 buttons |= wxJOY_BUTTON1;
2558 if (flags & JOY_BUTTON2)
2559 buttons |= wxJOY_BUTTON2;
2560 if (flags & JOY_BUTTON3)
2561 buttons |= wxJOY_BUTTON3;
2562 if (flags & JOY_BUTTON4)
2563 buttons |= wxJOY_BUTTON4;
2564
2565 wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN, buttons, joystick, change);
2566 event.SetPosition(wxPoint(x, y));
2567 event.SetEventObject(this);
2568
2569 GetEventHandler()->ProcessEvent(event);
2570 }
2571
2572 void wxWindow::MSWOnJoyUp(const int joystick, const int x, const int y, const WXUINT flags)
2573 {
2574 int buttons = 0;
2575 int change = 0;
2576 if (flags & JOY_BUTTON1CHG)
2577 change = wxJOY_BUTTON1;
2578 if (flags & JOY_BUTTON2CHG)
2579 change = wxJOY_BUTTON2;
2580 if (flags & JOY_BUTTON3CHG)
2581 change = wxJOY_BUTTON3;
2582 if (flags & JOY_BUTTON4CHG)
2583 change = wxJOY_BUTTON4;
2584
2585 if (flags & JOY_BUTTON1)
2586 buttons |= wxJOY_BUTTON1;
2587 if (flags & JOY_BUTTON2)
2588 buttons |= wxJOY_BUTTON2;
2589 if (flags & JOY_BUTTON3)
2590 buttons |= wxJOY_BUTTON3;
2591 if (flags & JOY_BUTTON4)
2592 buttons |= wxJOY_BUTTON4;
2593
2594 wxJoystickEvent event(wxEVT_JOY_BUTTON_UP, buttons, joystick, change);
2595 event.SetPosition(wxPoint(x, y));
2596 event.SetEventObject(this);
2597
2598 GetEventHandler()->ProcessEvent(event);
2599 }
2600
2601 void wxWindow::MSWOnJoyMove(const int joystick, const int x, const int y, const WXUINT flags)
2602 {
2603 int buttons = 0;
2604 if (flags & JOY_BUTTON1)
2605 buttons |= wxJOY_BUTTON1;
2606 if (flags & JOY_BUTTON2)
2607 buttons |= wxJOY_BUTTON2;
2608 if (flags & JOY_BUTTON3)
2609 buttons |= wxJOY_BUTTON3;
2610 if (flags & JOY_BUTTON4)
2611 buttons |= wxJOY_BUTTON4;
2612
2613 wxJoystickEvent event(wxEVT_JOY_MOVE, buttons, joystick, 0);
2614 event.SetPosition(wxPoint(x, y));
2615 event.SetEventObject(this);
2616
2617 GetEventHandler()->ProcessEvent(event);
2618 }
2619
2620 void wxWindow::MSWOnJoyZMove(const int joystick, const int z, const WXUINT flags)
2621 {
2622 int buttons = 0;
2623 if (flags & JOY_BUTTON1)
2624 buttons |= wxJOY_BUTTON1;
2625 if (flags & JOY_BUTTON2)
2626 buttons |= wxJOY_BUTTON2;
2627 if (flags & JOY_BUTTON3)
2628 buttons |= wxJOY_BUTTON3;
2629 if (flags & JOY_BUTTON4)
2630 buttons |= wxJOY_BUTTON4;
2631
2632 wxJoystickEvent event(wxEVT_JOY_ZMOVE, buttons, joystick, 0);
2633 event.SetZPosition(z);
2634 event.SetEventObject(this);
2635
2636 GetEventHandler()->ProcessEvent(event);
2637 }
2638
2639 void wxWindow::MSWOnVScroll(const WXWORD wParam, const WXWORD pos, const WXHWND control)
2640 {
2641 if (control)
2642 {
2643 wxWindow *child = wxFindWinFromHandle(control);
2644 if ( child )
2645 child->MSWOnVScroll(wParam, pos, control);
2646 return;
2647 }
2648
2649 wxScrollEvent event;
2650 event.SetPosition(pos);
2651 event.SetOrientation(wxVERTICAL);
2652 event.m_eventObject = this;
2653
2654 switch ( wParam )
2655 {
2656 case SB_TOP:
2657 event.m_eventType = wxEVENT_TYPE_SCROLL_TOP;
2658 break;
2659
2660 case SB_BOTTOM:
2661 event.m_eventType = wxEVENT_TYPE_SCROLL_BOTTOM;
2662 break;
2663
2664 case SB_LINEUP:
2665 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEUP;
2666 break;
2667
2668 case SB_LINEDOWN:
2669 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEDOWN;
2670 break;
2671
2672 case SB_PAGEUP:
2673 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEUP;
2674 break;
2675
2676 case SB_PAGEDOWN:
2677 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEDOWN;
2678 break;
2679
2680 case SB_THUMBTRACK:
2681 case SB_THUMBPOSITION:
2682 event.m_eventType = wxEVENT_TYPE_SCROLL_THUMBTRACK;
2683 break;
2684
2685 default:
2686 return;
2687 break;
2688 }
2689
2690 if (!GetEventHandler()->ProcessEvent(event))
2691 #if WXWIN_COMPATIBILITY
2692 GetEventHandler()->OldOnScroll(event);
2693 #else
2694 Default();
2695 #endif
2696 }
2697
2698 void wxWindow::MSWOnHScroll( const WXWORD wParam, const WXWORD pos, const WXHWND control)
2699 {
2700 if (control)
2701 {
2702 wxWindow *child = wxFindWinFromHandle(control);
2703 if ( child )
2704 child->MSWOnHScroll(wParam, pos, control);
2705 return;
2706 }
2707
2708 wxScrollEvent event;
2709 event.SetPosition(pos);
2710 event.SetOrientation(wxHORIZONTAL);
2711 event.m_eventObject = this;
2712
2713 switch ( wParam )
2714 {
2715 case SB_TOP:
2716 event.m_eventType = wxEVENT_TYPE_SCROLL_TOP;
2717 break;
2718
2719 case SB_BOTTOM:
2720 event.m_eventType = wxEVENT_TYPE_SCROLL_BOTTOM;
2721 break;
2722
2723 case SB_LINEUP:
2724 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEUP;
2725 break;
2726
2727 case SB_LINEDOWN:
2728 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEDOWN;
2729 break;
2730
2731 case SB_PAGEUP:
2732 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEUP;
2733 break;
2734
2735 case SB_PAGEDOWN:
2736 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEDOWN;
2737 break;
2738
2739 case SB_THUMBTRACK:
2740 case SB_THUMBPOSITION:
2741 event.m_eventType = wxEVENT_TYPE_SCROLL_THUMBTRACK;
2742 break;
2743
2744 default:
2745 return;
2746 break;
2747 }
2748 if (!GetEventHandler()->ProcessEvent(event))
2749 #if WXWIN_COMPATIBILITY
2750 GetEventHandler()->OldOnScroll(event);
2751 #else
2752 Default();
2753 #endif
2754 }
2755
2756 void wxWindow::MSWOnShow(bool show, int status)
2757 {
2758 wxShowEvent event(GetId(), show);
2759 event.m_eventObject = this;
2760 GetEventHandler()->ProcessEvent(event);
2761 }
2762
2763 bool wxWindow::MSWOnInitDialog(WXHWND WXUNUSED(hWndFocus))
2764 {
2765 wxInitDialogEvent event(GetId());
2766 event.m_eventObject = this;
2767 GetEventHandler()->ProcessEvent(event);
2768 return TRUE;
2769 }
2770
2771 void wxWindow::InitDialog(void)
2772 {
2773 wxInitDialogEvent event(GetId());
2774 event.SetEventObject( this );
2775 GetEventHandler()->ProcessEvent(event);
2776 }
2777
2778 // Default init dialog behaviour is to transfer data to window
2779 void wxWindow::OnInitDialog(wxInitDialogEvent& event)
2780 {
2781 TransferDataToWindow();
2782 }
2783
2784 void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
2785 {
2786 TEXTMETRIC tm;
2787 HDC dc = ::GetDC((HWND) wnd);
2788 HFONT fnt =0;
2789 HFONT was = 0;
2790 if (the_font)
2791 {
2792 #if DEBUG > 1
2793 wxDebugMsg("wxGetCharSize: Selecting HFONT %X\n", fnt);
2794 #endif
2795 // the_font->UseResource();
2796 // the_font->RealizeResource();
2797 if ((fnt=(HFONT) the_font->GetResourceHandle()))
2798 was = SelectObject(dc,fnt) ;
2799 }
2800 GetTextMetrics(dc, &tm);
2801 if (the_font && fnt && was)
2802 {
2803 #if DEBUG > 1
2804 wxDebugMsg("wxGetCharSize: Selecting old HFONT %X\n", was);
2805 #endif
2806 SelectObject(dc,was) ;
2807 }
2808 ReleaseDC((HWND)wnd, dc);
2809 *x = tm.tmAveCharWidth;
2810 *y = tm.tmHeight + tm.tmExternalLeading;
2811
2812 // if (the_font)
2813 // the_font->ReleaseResource();
2814 }
2815
2816 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
2817 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
2818 int wxCharCodeMSWToWX(int keySym)
2819 {
2820 int id = 0;
2821 switch (keySym)
2822 {
2823 case VK_CANCEL: id = WXK_CANCEL; break;
2824 case VK_BACK: id = WXK_BACK; break;
2825 case VK_TAB: id = WXK_TAB; break;
2826 case VK_CLEAR: id = WXK_CLEAR; break;
2827 case VK_RETURN: id = WXK_RETURN; break;
2828 case VK_SHIFT: id = WXK_SHIFT; break;
2829 case VK_CONTROL: id = WXK_CONTROL; break;
2830 case VK_MENU : id = WXK_MENU; break;
2831 case VK_PAUSE: id = WXK_PAUSE; break;
2832 case VK_SPACE: id = WXK_SPACE; break;
2833 case VK_ESCAPE: id = WXK_ESCAPE; break;
2834 case VK_PRIOR: id = WXK_PRIOR; break;
2835 case VK_NEXT : id = WXK_NEXT; break;
2836 case VK_END: id = WXK_END; break;
2837 case VK_HOME : id = WXK_HOME; break;
2838 case VK_LEFT : id = WXK_LEFT; break;
2839 case VK_UP: id = WXK_UP; break;
2840 case VK_RIGHT: id = WXK_RIGHT; break;
2841 case VK_DOWN : id = WXK_DOWN; break;
2842 case VK_SELECT: id = WXK_SELECT; break;
2843 case VK_PRINT: id = WXK_PRINT; break;
2844 case VK_EXECUTE: id = WXK_EXECUTE; break;
2845 case VK_INSERT: id = WXK_INSERT; break;
2846 case VK_DELETE: id = WXK_DELETE; break;
2847 case VK_HELP : id = WXK_HELP; break;
2848 case VK_NUMPAD0: id = WXK_NUMPAD0; break;
2849 case VK_NUMPAD1: id = WXK_NUMPAD1; break;
2850 case VK_NUMPAD2: id = WXK_NUMPAD2; break;
2851 case VK_NUMPAD3: id = WXK_NUMPAD3; break;
2852 case VK_NUMPAD4: id = WXK_NUMPAD4; break;
2853 case VK_NUMPAD5: id = WXK_NUMPAD5; break;
2854 case VK_NUMPAD6: id = WXK_NUMPAD6; break;
2855 case VK_NUMPAD7: id = WXK_NUMPAD7; break;
2856 case VK_NUMPAD8: id = WXK_NUMPAD8; break;
2857 case VK_NUMPAD9: id = WXK_NUMPAD9; break;
2858 case VK_MULTIPLY: id = WXK_MULTIPLY; break;
2859 case VK_ADD: id = WXK_ADD; break;
2860 case VK_SUBTRACT: id = WXK_SUBTRACT; break;
2861 case VK_DECIMAL: id = WXK_DECIMAL; break;
2862 case VK_DIVIDE: id = WXK_DIVIDE; break;
2863 case VK_F1: id = WXK_F1; break;
2864 case VK_F2: id = WXK_F2; break;
2865 case VK_F3: id = WXK_F3; break;
2866 case VK_F4: id = WXK_F4; break;
2867 case VK_F5: id = WXK_F5; break;
2868 case VK_F6: id = WXK_F6; break;
2869 case VK_F7: id = WXK_F7; break;
2870 case VK_F8: id = WXK_F8; break;
2871 case VK_F9: id = WXK_F9; break;
2872 case VK_F10: id = WXK_F10; break;
2873 case VK_F11: id = WXK_F11; break;
2874 case VK_F12: id = WXK_F12; break;
2875 case VK_F13: id = WXK_F13; break;
2876 case VK_F14: id = WXK_F14; break;
2877 case VK_F15: id = WXK_F15; break;
2878 case VK_F16: id = WXK_F16; break;
2879 case VK_F17: id = WXK_F17; break;
2880 case VK_F18: id = WXK_F18; break;
2881 case VK_F19: id = WXK_F19; break;
2882 case VK_F20: id = WXK_F20; break;
2883 case VK_F21: id = WXK_F21; break;
2884 case VK_F22: id = WXK_F22; break;
2885 case VK_F23: id = WXK_F23; break;
2886 case VK_F24: id = WXK_F24; break;
2887 case VK_NUMLOCK: id = WXK_NUMLOCK; break;
2888 case VK_SCROLL: id = WXK_SCROLL; break;
2889 default:
2890 {
2891 return 0;
2892 }
2893 }
2894 return id;
2895 }
2896
2897 int wxCharCodeWXToMSW(int id, bool *isVirtual)
2898 {
2899 *isVirtual = TRUE;
2900 int keySym = 0;
2901 switch (id)
2902 {
2903 case WXK_CANCEL: keySym = VK_CANCEL; break;
2904 case WXK_CLEAR: keySym = VK_CLEAR; break;
2905 case WXK_SHIFT: keySym = VK_SHIFT; break;
2906 case WXK_CONTROL: keySym = VK_CONTROL; break;
2907 case WXK_MENU : keySym = VK_MENU; break;
2908 case WXK_PAUSE: keySym = VK_PAUSE; break;
2909 case WXK_PRIOR: keySym = VK_PRIOR; break;
2910 case WXK_NEXT : keySym = VK_NEXT; break;
2911 case WXK_END: keySym = VK_END; break;
2912 case WXK_HOME : keySym = VK_HOME; break;
2913 case WXK_LEFT : keySym = VK_LEFT; break;
2914 case WXK_UP: keySym = VK_UP; break;
2915 case WXK_RIGHT: keySym = VK_RIGHT; break;
2916 case WXK_DOWN : keySym = VK_DOWN; break;
2917 case WXK_SELECT: keySym = VK_SELECT; break;
2918 case WXK_PRINT: keySym = VK_PRINT; break;
2919 case WXK_EXECUTE: keySym = VK_EXECUTE; break;
2920 case WXK_INSERT: keySym = VK_INSERT; break;
2921 case WXK_DELETE: keySym = VK_DELETE; break;
2922 case WXK_HELP : keySym = VK_HELP; break;
2923 case WXK_NUMPAD0: keySym = VK_NUMPAD0; break;
2924 case WXK_NUMPAD1: keySym = VK_NUMPAD1; break;
2925 case WXK_NUMPAD2: keySym = VK_NUMPAD2; break;
2926 case WXK_NUMPAD3: keySym = VK_NUMPAD3; break;
2927 case WXK_NUMPAD4: keySym = VK_NUMPAD4; break;
2928 case WXK_NUMPAD5: keySym = VK_NUMPAD5; break;
2929 case WXK_NUMPAD6: keySym = VK_NUMPAD6; break;
2930 case WXK_NUMPAD7: keySym = VK_NUMPAD7; break;
2931 case WXK_NUMPAD8: keySym = VK_NUMPAD8; break;
2932 case WXK_NUMPAD9: keySym = VK_NUMPAD9; break;
2933 case WXK_MULTIPLY: keySym = VK_MULTIPLY; break;
2934 case WXK_ADD: keySym = VK_ADD; break;
2935 case WXK_SUBTRACT: keySym = VK_SUBTRACT; break;
2936 case WXK_DECIMAL: keySym = VK_DECIMAL; break;
2937 case WXK_DIVIDE: keySym = VK_DIVIDE; break;
2938 case WXK_F1: keySym = VK_F1; break;
2939 case WXK_F2: keySym = VK_F2; break;
2940 case WXK_F3: keySym = VK_F3; break;
2941 case WXK_F4: keySym = VK_F4; break;
2942 case WXK_F5: keySym = VK_F5; break;
2943 case WXK_F6: keySym = VK_F6; break;
2944 case WXK_F7: keySym = VK_F7; break;
2945 case WXK_F8: keySym = VK_F8; break;
2946 case WXK_F9: keySym = VK_F9; break;
2947 case WXK_F10: keySym = VK_F10; break;
2948 case WXK_F11: keySym = VK_F11; break;
2949 case WXK_F12: keySym = VK_F12; break;
2950 case WXK_F13: keySym = VK_F13; break;
2951 case WXK_F14: keySym = VK_F14; break;
2952 case WXK_F15: keySym = VK_F15; break;
2953 case WXK_F16: keySym = VK_F16; break;
2954 case WXK_F17: keySym = VK_F17; break;
2955 case WXK_F18: keySym = VK_F18; break;
2956 case WXK_F19: keySym = VK_F19; break;
2957 case WXK_F20: keySym = VK_F20; break;
2958 case WXK_F21: keySym = VK_F21; break;
2959 case WXK_F22: keySym = VK_F22; break;
2960 case WXK_F23: keySym = VK_F23; break;
2961 case WXK_F24: keySym = VK_F24; break;
2962 case WXK_NUMLOCK: keySym = VK_NUMLOCK; break;
2963 case WXK_SCROLL: keySym = VK_SCROLL; break;
2964 default:
2965 {
2966 *isVirtual = FALSE;
2967 keySym = id;
2968 break;
2969 }
2970 }
2971 return keySym;
2972 }
2973
2974 // Caret manipulation
2975 void wxWindow::CreateCaret(const int w, const int h)
2976 {
2977 m_caretWidth = w;
2978 m_caretHeight = h;
2979 m_caretEnabled = TRUE;
2980 }
2981
2982 void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
2983 {
2984 // Not implemented
2985 }
2986
2987 void wxWindow::ShowCaret(const bool show)
2988 {
2989 if (m_caretEnabled)
2990 {
2991 if (show)
2992 ::ShowCaret((HWND) GetHWND());
2993 else
2994 ::HideCaret((HWND) GetHWND());
2995 m_caretShown = show;
2996 }
2997 }
2998
2999 void wxWindow::DestroyCaret(void)
3000 {
3001 m_caretEnabled = FALSE;
3002 }
3003
3004 void wxWindow::SetCaretPos(const int x, const int y)
3005 {
3006 ::SetCaretPos(x, y);
3007 }
3008
3009 void wxWindow::GetCaretPos(int *x, int *y) const
3010 {
3011 POINT point;
3012 ::GetCaretPos(&point);
3013 *x = point.x;
3014 *y = point.y;
3015 }
3016
3017 /*
3018 * Update iterator. Use from within OnPaint.
3019 */
3020
3021 static RECT gs_UpdateRect;
3022
3023 wxUpdateIterator::wxUpdateIterator(wxWindow* wnd)
3024 {
3025 current = 0; //start somewhere...
3026 #if defined(__WIN32__) && !defined(__win32s__)
3027 rlist = NULL; //make sure I don't free randomly
3028 int len = GetRegionData((HRGN) wnd->m_updateRgn,0,NULL); //Get buffer size
3029 if (len)
3030 {
3031 rlist = (WXRGNDATA *) (RGNDATA *)new char[len];
3032 GetRegionData((HRGN) wnd->m_updateRgn,len, (RGNDATA *)rlist);
3033 rp = (void *)(RECT*) ((RGNDATA *)rlist)->Buffer;
3034 rects = ((RGNDATA *)rlist)->rdh.nCount;
3035 }
3036 else
3037 #endif
3038 {
3039 gs_UpdateRect.left = wnd->m_updateRect.x;
3040 gs_UpdateRect.top = wnd->m_updateRect.y;
3041 gs_UpdateRect.right = wnd->m_updateRect.x + wnd->m_updateRect.width;
3042 gs_UpdateRect.bottom = wnd->m_updateRect.y + wnd->m_updateRect.height;
3043 rects = 1;
3044 rp = (void *)&gs_UpdateRect; //Only one available in Win16,32s
3045 }
3046 }
3047
3048 wxUpdateIterator::~wxUpdateIterator(void)
3049 {
3050 #ifdef __WIN32__
3051 #ifndef __win32s__
3052 if (rlist) delete (RGNDATA *) rlist;
3053 #endif
3054 #endif
3055 }
3056
3057 wxUpdateIterator::operator int (void)
3058 {
3059 if (current < rects)
3060 {
3061 return TRUE;
3062 }
3063 else
3064 {
3065 return FALSE;
3066 }
3067 }
3068
3069 wxUpdateIterator* wxUpdateIterator::operator ++(int)
3070 {
3071 current++;
3072 return this;
3073 }
3074
3075 void wxUpdateIterator::GetRect(wxRect *rect)
3076 {
3077 RECT *mswRect = ((RECT *)rp)+current; //ought to error check this...
3078 rect->x = mswRect->left;
3079 rect->y = mswRect->top;
3080 rect->width = mswRect->right - mswRect->left;
3081 rect->height = mswRect->bottom - mswRect->top;
3082 }
3083
3084 int wxUpdateIterator::GetX()
3085 {
3086 return ((RECT*)rp)[current].left;
3087 }
3088
3089 int wxUpdateIterator::GetY()
3090 {
3091 return ((RECT *)rp)[current].top;
3092 }
3093
3094 int wxUpdateIterator::GetW()
3095 {
3096 return ((RECT *)rp)[current].right-GetX();
3097 }
3098
3099 int wxUpdateIterator::GetH()
3100 {
3101 return ((RECT *)rp)[current].bottom-GetY();
3102 }
3103
3104 wxWindow *wxGetActiveWindow(void)
3105 {
3106 HWND hWnd = GetActiveWindow();
3107 if (hWnd != 0)
3108 {
3109 return wxFindWinFromHandle((WXHWND) hWnd);
3110 }
3111 return NULL;
3112 }
3113
3114 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
3115 // in active frames and dialogs, regardless of where the focus is.
3116 static HHOOK wxTheKeyboardHook = 0;
3117 static FARPROC wxTheKeyboardHookProc = 0;
3118 int APIENTRY _EXPORT
3119 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam);
3120
3121 void wxSetKeyboardHook(bool doIt)
3122 {
3123 if (doIt)
3124 {
3125 wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
3126 wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
3127 #ifdef __WIN32__
3128 GetCurrentThreadId());
3129 // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
3130 #else
3131 GetCurrentTask());
3132 #endif
3133 }
3134 else
3135 {
3136 UnhookWindowsHookEx(wxTheKeyboardHook);
3137 FreeProcInstance(wxTheKeyboardHookProc);
3138 }
3139 }
3140
3141 int APIENTRY _EXPORT
3142 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
3143 {
3144 DWORD hiWord = HIWORD(lParam);
3145 if (nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0))
3146 {
3147 int id;
3148 if ((id = wxCharCodeMSWToWX(wParam)) != 0)
3149 {
3150 wxKeyEvent event(wxEVT_CHAR_HOOK);
3151 if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
3152 event.m_altDown = TRUE;
3153
3154 event.m_eventObject = NULL;
3155 event.m_keyCode = id;
3156 /* begin Albert's fix for control and shift key 26.5 */
3157 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
3158 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
3159 /* end Albert's fix for control and shift key 26.5 */
3160 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
3161
3162 #if WXWIN_COMPATIBILITY
3163 if ( wxTheApp && wxTheApp->OldOnCharHook(event) )
3164 return 1;
3165 #endif
3166 wxWindow *win = wxGetActiveWindow();
3167 if (win)
3168 {
3169 if (win->GetEventHandler()->ProcessEvent(event))
3170 return 1;
3171 }
3172 else
3173 {
3174 if ( wxTheApp && wxTheApp->ProcessEvent(event) )
3175 return 1;
3176 }
3177 }
3178 }
3179 return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
3180 }
3181
3182 void wxWindow::SetSizeHints(const int minW, const int minH, const int maxW, const int maxH, const int WXUNUSED(incW), const int WXUNUSED(incH))
3183 {
3184 m_minSizeX = minW;
3185 m_minSizeY = minH;
3186 m_maxSizeX = maxW;
3187 m_maxSizeY = maxH;
3188 }
3189
3190 void wxWindow::Centre(const int direction)
3191 {
3192 int x, y, width, height, panel_width, panel_height, new_x, new_y;
3193
3194 wxWindow *father = (wxWindow *)GetParent();
3195 if (!father)
3196 return;
3197
3198 father->GetClientSize(&panel_width, &panel_height);
3199 GetSize(&width, &height);
3200 GetPosition(&x, &y);
3201
3202 new_x = -1;
3203 new_y = -1;
3204
3205 if (direction & wxHORIZONTAL)
3206 new_x = (int)((panel_width - width)/2);
3207
3208 if (direction & wxVERTICAL)
3209 new_y = (int)((panel_height - height)/2);
3210
3211 SetSize(new_x, new_y, -1, -1);
3212
3213 }
3214
3215 /* TODO (maybe)
3216 void wxWindow::OnPaint(void)
3217 {
3218 PaintSelectionHandles();
3219 }
3220 */
3221
3222 void wxWindow::WarpPointer (const int x_pos, const int y_pos)
3223 {
3224 // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
3225 // pixel coordinates, relatives to the canvas -- So, we first need to
3226 // substract origin of the window, then convert to screen position
3227
3228 int x = x_pos; int y = y_pos;
3229 /* Leave this to the app to decide (and/or wxScrolledWindow)
3230 x -= m_xScrollPosition * m_xScrollPixelsPerLine;
3231 y -= m_yScrollPosition * m_yScrollPixelsPerLine;
3232 */
3233 RECT rect;
3234 GetWindowRect ((HWND) GetHWND(), &rect);
3235
3236 x += rect.left;
3237 y += rect.top;
3238
3239 SetCursorPos (x, y);
3240 }
3241
3242 void wxWindow::MSWDeviceToLogical (float *x, float *y) const
3243 {
3244 // TODO
3245 // Do we have a SetUserScale in wxWindow too, so we can
3246 // get mouse events scaled?
3247 /*
3248 if (m_windowDC)
3249 {
3250 *x = m_windowDC->DeviceToLogicalX ((int) *x);
3251 *y = m_windowDC->DeviceToLogicalY ((int) *y);
3252 }
3253 */
3254 }
3255
3256 bool wxWindow::MSWOnEraseBkgnd (const WXHDC pDC)
3257 {
3258 wxDC dc ;
3259
3260 dc.SetHDC(pDC);
3261 dc.SetWindow(this);
3262 dc.BeginDrawing();
3263
3264 wxEraseEvent event(m_windowId, &dc);
3265 event.m_eventObject = this;
3266 if (!GetEventHandler()->ProcessEvent(event))
3267 {
3268 dc.EndDrawing();
3269 dc.SelectOldObjects(pDC);
3270 return FALSE;
3271 }
3272 else
3273 {
3274 dc.EndDrawing();
3275 dc.SelectOldObjects(pDC);
3276 }
3277
3278 dc.SetHDC((WXHDC) NULL);
3279 return TRUE;
3280 }
3281
3282 void wxWindow::OnEraseBackground(wxEraseEvent& event)
3283 {
3284 RECT rect;
3285 ::GetClientRect((HWND) GetHWND(), &rect);
3286
3287 HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
3288 int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
3289
3290 // ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
3291 ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
3292 ::DeleteObject(hBrush);
3293 ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
3294 /*
3295 // Less efficient version (and doesn't account for scrolling)
3296 int w, h;
3297 GetClientSize(& w, & h);
3298 wxBrush *brush = wxTheBrushList->FindOrCreateBrush(& GetBackgroundColour(), wxSOLID);
3299 event.GetDC()->SetBrush(brush);
3300 event.GetDC()->SetPen(wxTRANSPARENT_PEN);
3301
3302 event.GetDC()->DrawRectangle(0, 0, w+1, h+1);
3303 */
3304 }
3305
3306 #if WXWIN_COMPATIBILITY
3307 void wxWindow::SetScrollRange(const int orient, const int range, const bool refresh)
3308 {
3309 #if defined(__WIN95__)
3310
3311 int range1 = range;
3312
3313 // Try to adjust the range to cope with page size > 1
3314 // - a Windows API quirk
3315 int pageSize = GetScrollPage(orient);
3316 if ( pageSize > 1 && range > 0)
3317 {
3318 range1 += (pageSize - 1);
3319 }
3320
3321 SCROLLINFO info;
3322 int dir;
3323
3324 if (orient == wxHORIZONTAL) {
3325 dir = SB_HORZ;
3326 } else {
3327 dir = SB_VERT;
3328 }
3329
3330 info.cbSize = sizeof(SCROLLINFO);
3331 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3332 info.nMin = 0;
3333 info.nMax = range1;
3334 info.nPos = 0;
3335 info.fMask = SIF_RANGE | SIF_PAGE;
3336
3337 HWND hWnd = (HWND) GetHWND();
3338 if (hWnd)
3339 ::SetScrollInfo(hWnd, dir, &info, refresh);
3340 #else
3341 int wOrient ;
3342 if (orient == wxHORIZONTAL)
3343 wOrient = SB_HORZ;
3344 else
3345 wOrient = SB_VERT;
3346
3347 HWND hWnd = (HWND) GetHWND();
3348 if (hWnd)
3349 ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
3350 #endif
3351 }
3352
3353 void wxWindow::SetScrollPage(const int orient, const int page, const bool refresh)
3354 {
3355 #if defined(__WIN95__)
3356 SCROLLINFO info;
3357 int dir;
3358
3359 if (orient == wxHORIZONTAL) {
3360 dir = SB_HORZ;
3361 m_xThumbSize = page;
3362 } else {
3363 dir = SB_VERT;
3364 m_yThumbSize = page;
3365 }
3366
3367 info.cbSize = sizeof(SCROLLINFO);
3368 info.nPage = page;
3369 info.nMin = 0;
3370 info.fMask = SIF_PAGE ;
3371
3372 HWND hWnd = (HWND) GetHWND();
3373 if (hWnd)
3374 ::SetScrollInfo(hWnd, dir, &info, refresh);
3375 #else
3376 if (orient == wxHORIZONTAL)
3377 m_xThumbSize = page;
3378 else
3379 m_yThumbSize = page;
3380 #endif
3381 }
3382
3383 int wxWindow::OldGetScrollRange(const int orient) const
3384 {
3385 int wOrient ;
3386 if (orient == wxHORIZONTAL)
3387 wOrient = SB_HORZ;
3388 else
3389 wOrient = SB_VERT;
3390
3391 #if __WATCOMC__ && defined(__WINDOWS_386__)
3392 short minPos, maxPos;
3393 #else
3394 int minPos, maxPos;
3395 #endif
3396 HWND hWnd = (HWND) GetHWND();
3397 if (hWnd)
3398 {
3399 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3400 #if defined(__WIN95__)
3401 // Try to adjust the range to cope with page size > 1
3402 // - a Windows API quirk
3403 int pageSize = GetScrollPage(orient);
3404 if ( pageSize > 1 )
3405 {
3406 maxPos -= (pageSize - 1);
3407 }
3408 #endif
3409 return maxPos;
3410 }
3411 else
3412 return 0;
3413 }
3414
3415 int wxWindow::GetScrollPage(const int orient) const
3416 {
3417 if (orient == wxHORIZONTAL)
3418 return m_xThumbSize;
3419 else
3420 return m_yThumbSize;
3421 }
3422 #endif
3423
3424 int wxWindow::GetScrollPos(const int orient) const
3425 {
3426 int wOrient ;
3427 if (orient == wxHORIZONTAL)
3428 wOrient = SB_HORZ;
3429 else
3430 wOrient = SB_VERT;
3431 HWND hWnd = (HWND) GetHWND();
3432 if (hWnd)
3433 {
3434 return ::GetScrollPos(hWnd, wOrient);
3435 }
3436 else
3437 return 0;
3438 }
3439
3440 // This now returns the whole range, not just the number
3441 // of positions that we can scroll.
3442 int wxWindow::GetScrollRange(const int orient) const
3443 {
3444 int wOrient ;
3445 if (orient == wxHORIZONTAL)
3446 wOrient = SB_HORZ;
3447 else
3448 wOrient = SB_VERT;
3449
3450 #if __WATCOMC__ && defined(__WINDOWS_386__)
3451 short minPos, maxPos;
3452 #else
3453 int minPos, maxPos;
3454 #endif
3455 HWND hWnd = (HWND) GetHWND();
3456 if (hWnd)
3457 {
3458 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3459 #if defined(__WIN95__)
3460 // Try to adjust the range to cope with page size > 1
3461 // - a Windows API quirk
3462 int pageSize = GetScrollPage(orient);
3463 if ( pageSize > 1 )
3464 {
3465 maxPos -= (pageSize - 1);
3466 }
3467 // October 10th: new range concept.
3468 maxPos += pageSize;
3469 #endif
3470
3471 return maxPos;
3472 }
3473 else
3474 return 0;
3475 }
3476
3477 int wxWindow::GetScrollThumb(const int orient) const
3478 {
3479 if (orient == wxHORIZONTAL)
3480 return m_xThumbSize;
3481 else
3482 return m_yThumbSize;
3483 }
3484
3485 void wxWindow::SetScrollPos(const int orient, const int pos, const bool refresh)
3486 {
3487 #if defined(__WIN95__)
3488 SCROLLINFO info;
3489 int dir;
3490
3491 if (orient == wxHORIZONTAL) {
3492 dir = SB_HORZ;
3493 } else {
3494 dir = SB_VERT;
3495 }
3496
3497 info.cbSize = sizeof(SCROLLINFO);
3498 info.nPage = 0;
3499 info.nMin = 0;
3500 info.nPos = pos;
3501 info.fMask = SIF_POS ;
3502
3503 HWND hWnd = (HWND) GetHWND();
3504 if (hWnd)
3505 ::SetScrollInfo(hWnd, dir, &info, refresh);
3506 #else
3507 int wOrient ;
3508 if (orient == wxHORIZONTAL)
3509 wOrient = SB_HORZ;
3510 else
3511 wOrient = SB_VERT;
3512
3513 HWND hWnd = (HWND) GetHWND();
3514 if (hWnd)
3515 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3516 #endif
3517 }
3518
3519 // New function that will replace some of the above.
3520 void wxWindow::SetScrollbar(const int orient, const int pos, const int thumbVisible,
3521 const int range, const bool refresh)
3522 {
3523 /*
3524 SetScrollPage(orient, thumbVisible, FALSE);
3525
3526 int oldRange = range - thumbVisible ;
3527 SetScrollRange(orient, oldRange, FALSE);
3528
3529 SetScrollPos(orient, pos, refresh);
3530 */
3531 #if defined(__WIN95__)
3532 int oldRange = range - thumbVisible ;
3533
3534 int range1 = oldRange;
3535
3536 // Try to adjust the range to cope with page size > 1
3537 // - a Windows API quirk
3538 int pageSize = thumbVisible;
3539 if ( pageSize > 1 && range > 0)
3540 {
3541 range1 += (pageSize - 1);
3542 }
3543
3544 SCROLLINFO info;
3545 int dir;
3546
3547 if (orient == wxHORIZONTAL) {
3548 dir = SB_HORZ;
3549 } else {
3550 dir = SB_VERT;
3551 }
3552
3553 info.cbSize = sizeof(SCROLLINFO);
3554 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3555 info.nMin = 0;
3556 info.nMax = range1;
3557 info.nPos = pos;
3558 info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
3559
3560 HWND hWnd = (HWND) GetHWND();
3561 if (hWnd)
3562 ::SetScrollInfo(hWnd, dir, &info, refresh);
3563 #else
3564 int wOrient ;
3565 if (orient == wxHORIZONTAL)
3566 wOrient = SB_HORZ;
3567 else
3568 wOrient = SB_VERT;
3569
3570 HWND hWnd = (HWND) GetHWND();
3571 if (hWnd)
3572 {
3573 ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
3574 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3575 }
3576 #endif
3577 if (orient == wxHORIZONTAL) {
3578 m_xThumbSize = thumbVisible;
3579 } else {
3580 m_yThumbSize = thumbVisible;
3581 }
3582 }
3583
3584 void wxWindow::ScrollWindow(const int dx, const int dy, const wxRectangle *rect)
3585 {
3586 RECT rect2;
3587 if ( rect )
3588 {
3589 rect2.left = rect->x;
3590 rect2.top = rect->y;
3591 rect2.right = rect->x + rect->width;
3592 rect2.bottom = rect->y + rect->height;
3593 }
3594
3595 if ( rect )
3596 ::ScrollWindow((HWND) GetHWND(), dx, dy, &rect2, NULL);
3597 else
3598 ::ScrollWindow((HWND) GetHWND(), dx, dy, NULL, NULL);
3599 }
3600
3601 void wxWindow::OnSize(wxSizeEvent& event)
3602 {
3603 Default();
3604 #if USE_CONSTRAINTS
3605 if (GetAutoLayout())
3606 Layout();
3607 #endif
3608 }
3609
3610 /*
3611 void wxWindow::CalcScrolledPosition(const int x, const int y, int *xx, int *yy) const
3612 {
3613 *xx = x;
3614 *yy = y;
3615 }
3616
3617 void wxWindow::CalcUnscrolledPosition(const int x, const int y, float *xx, float *yy) const
3618 {
3619 *xx = x;
3620 *yy = y;
3621 }
3622 */
3623
3624 void wxWindow::SetFont(const wxFont& font)
3625 {
3626 // Decrement the usage count of the old label font
3627 // (we may be able to free it up)
3628 // if (GetFont()->Ok())
3629 // GetFont()->ReleaseResource();
3630
3631 m_windowFont = font;
3632
3633 if (!m_windowFont.Ok())
3634 return;
3635
3636 // m_windowFont.UseResource();
3637
3638 HWND hWnd = (HWND) GetHWND();
3639 if (hWnd != 0)
3640 {
3641 // m_windowFont.RealizeResource();
3642
3643 if (m_windowFont.GetResourceHandle())
3644 SendMessage(hWnd, WM_SETFONT,
3645 (WPARAM)m_windowFont.GetResourceHandle(),TRUE);
3646 }
3647 }
3648
3649 void wxWindow::SubclassWin(WXHWND hWnd)
3650 {
3651 wxAssociateWinWithHandle((HWND)hWnd, this);
3652
3653 m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC);
3654 SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc);
3655 }
3656
3657 void wxWindow::UnsubclassWin(void)
3658 {
3659 wxRemoveHandleAssociation(this);
3660
3661 // Restore old Window proc
3662 if ((HWND) GetHWND())
3663 {
3664 FARPROC farProc = (FARPROC) GetWindowLong((HWND) GetHWND(), GWL_WNDPROC);
3665 if ((m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc))
3666 {
3667 SetWindowLong((HWND) GetHWND(), GWL_WNDPROC, (LONG) m_oldWndProc);
3668 m_oldWndProc = 0;
3669 }
3670 }
3671 }
3672
3673 // Make a Windows extended style from the given wxWindows window style
3674 WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders)
3675 {
3676 WXDWORD exStyle = 0;
3677 if ( style & wxTRANSPARENT_WINDOW )
3678 exStyle |= WS_EX_TRANSPARENT ;
3679
3680 if ( !eliminateBorders )
3681 {
3682 if ( style & wxSUNKEN_BORDER )
3683 exStyle |= WS_EX_CLIENTEDGE ;
3684 if ( style & wxDOUBLE_BORDER )
3685 exStyle |= WS_EX_DLGMODALFRAME ;
3686 #if defined(__WIN95__)
3687 if ( style & wxRAISED_BORDER )
3688 exStyle |= WS_EX_WINDOWEDGE ;
3689 if ( style & wxSTATIC_BORDER )
3690 exStyle |= WS_EX_STATICEDGE ;
3691 #endif
3692 }
3693 return exStyle;
3694 }
3695
3696 // Determines whether native 3D effects or CTL3D should be used,
3697 // applying a default border style if required, and returning an extended
3698 // style to pass to CreateWindowEx.
3699 WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
3700 {
3701 // If matches certain criteria, then assume no 3D effects
3702 // unless specifically requested (dealt with in MakeExtendedStyle)
3703 if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
3704 {
3705 *want3D = FALSE;
3706 return MakeExtendedStyle(m_windowStyle, FALSE);
3707 }
3708
3709 // Determine whether we should be using 3D effects or not.
3710 bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
3711
3712 // 1) App can specify global 3D effects
3713 *want3D = wxTheApp->GetAuto3D();
3714
3715 // 2) If the parent is being drawn with user colours, or simple border specified,
3716 // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
3717 if (GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER))
3718 *want3D = FALSE;
3719
3720 // 3) Control can override this global setting by defining
3721 // a border style, e.g. wxSUNKEN_BORDER
3722 if (m_windowStyle & wxSUNKEN_BORDER )
3723 *want3D = TRUE;
3724
3725 // 4) If it's a special border, CTL3D can't cope so we want a native border
3726 if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
3727 (m_windowStyle & wxSTATIC_BORDER) )
3728 {
3729 *want3D = TRUE;
3730 nativeBorder = TRUE;
3731 }
3732
3733 // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
3734 // effects from extended style
3735 #if CTL3D
3736 if ( *want3D )
3737 nativeBorder = FALSE;
3738 #endif
3739
3740 DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
3741
3742 // If we want 3D, but haven't specified a border here,
3743 // apply the default border style specified.
3744 // TODO what about non-Win95 WIN32? Does it have borders?
3745 #if defined(__WIN95__) && !CTL3D
3746 if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
3747 (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
3748 exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
3749 #endif
3750
3751 return exStyle;
3752 }
3753
3754 #if WXWIN_COMPATIBILITY
3755 void wxWindow::OldOnPaint(void)
3756 {
3757 wxPaintEvent event(m_windowId);
3758 event.m_eventObject = this;
3759 if (!GetEventHandler()->ProcessEvent(event))
3760 Default();
3761 };
3762
3763 void wxWindow::OldOnSize(int w, int h)
3764 {
3765 wxSizeEvent event(wxSize(w, h), m_windowId);
3766 event.m_eventObject = this;
3767 if (!GetEventHandler()->ProcessEvent(event))
3768 Default();
3769 };
3770
3771 void wxWindow::OldOnMouseEvent(wxMouseEvent& event)
3772 {
3773 if (!GetEventHandler()->ProcessEvent(event))
3774 Default();
3775 };
3776
3777 void wxWindow::OldOnChar(wxKeyEvent& event)
3778 {
3779 if (!GetEventHandler()->ProcessEvent(event))
3780 Default();
3781 };
3782
3783 void wxWindow::OldOnSetFocus(void)
3784 {
3785 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
3786 event.m_eventObject = this;
3787 if (!GetEventHandler()->ProcessEvent(event))
3788 Default();
3789 };
3790
3791 void wxWindow::OldOnKillFocus(void)
3792 {
3793 wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
3794 event.m_eventObject = this;
3795 if (!GetEventHandler()->ProcessEvent(event))
3796 Default();
3797 };
3798 #endif
3799
3800 void wxWindow::OnChar(wxKeyEvent& event)
3801 {
3802 bool isVirtual;
3803 int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
3804
3805 if ( id == -1 )
3806 id= m_lastWParam;
3807
3808 if ( !event.ControlDown() )
3809 (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
3810 }
3811
3812 void wxWindow::OnPaint(wxPaintEvent& event)
3813 {
3814 Default();
3815 }
3816
3817 bool wxWindow::IsEnabled(void) const
3818 {
3819 return (::IsWindowEnabled((HWND) GetHWND()) != 0);
3820 }
3821
3822 // Dialog support: override these and call
3823 // base class members to add functionality
3824 // that can't be done using validators.
3825 // NOTE: these functions assume that controls
3826 // are direct children of this window, not grandchildren
3827 // or other levels of descendant.
3828
3829 // Transfer values to controls. If returns FALSE,
3830 // it's an application error (pops up a dialog)
3831 bool wxWindow::TransferDataToWindow(void)
3832 {
3833 wxNode *node = GetChildren()->First();
3834 while ( node )
3835 {
3836 wxWindow *child = (wxWindow *)node->Data();
3837 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
3838 !child->GetValidator()->TransferToWindow() )
3839 {
3840 wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
3841 return FALSE;
3842 }
3843
3844 node = node->Next();
3845 }
3846 return TRUE;
3847 }
3848
3849 // Transfer values from controls. If returns FALSE,
3850 // validation failed: don't quit
3851 bool wxWindow::TransferDataFromWindow(void)
3852 {
3853 wxNode *node = GetChildren()->First();
3854 while ( node )
3855 {
3856 wxWindow *child = (wxWindow *)node->Data();
3857 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
3858 {
3859 return FALSE;
3860 }
3861
3862 node = node->Next();
3863 }
3864 return TRUE;
3865 }
3866
3867 bool wxWindow::Validate(void)
3868 {
3869 wxNode *node = GetChildren()->First();
3870 while ( node )
3871 {
3872 wxWindow *child = (wxWindow *)node->Data();
3873 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this) )
3874 {
3875 return FALSE;
3876 }
3877
3878 node = node->Next();
3879 }
3880 return TRUE;
3881 }
3882
3883 // Get the window with the focus
3884 wxWindow *wxWindow::FindFocus(void)
3885 {
3886 HWND hWnd = ::GetFocus();
3887 if ( hWnd )
3888 {
3889 return wxFindWinFromHandle((WXHWND) hWnd);
3890 }
3891 return NULL;
3892 }
3893
3894 void wxWindow::AddChild(wxWindow *child)
3895 {
3896 GetChildren()->Append(child);
3897 child->m_windowParent = this;
3898 }
3899
3900 void wxWindow::RemoveChild(wxWindow *child)
3901 {
3902 if (GetChildren())
3903 GetChildren()->DeleteObject(child);
3904 child->m_windowParent = NULL;
3905 }
3906
3907 void wxWindow::DestroyChildren(void)
3908 {
3909 if (GetChildren()) {
3910 wxNode *node;
3911 while ((node = GetChildren()->First()) != (wxNode *)NULL) {
3912 wxWindow *child;
3913 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) {
3914 delete child;
3915 if ( GetChildren()->Member(child) )
3916 delete node;
3917 }
3918 } /* while */
3919 }
3920 }
3921
3922 void wxWindow::MakeModal(const bool modal)
3923 {
3924 // Disable all other windows
3925 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
3926 {
3927 wxNode *node = wxTopLevelWindows.First();
3928 while (node)
3929 {
3930 wxWindow *win = (wxWindow *)node->Data();
3931 if (win != this)
3932 win->Enable(!modal);
3933
3934 node = node->Next();
3935 }
3936 }
3937 }
3938
3939 // If nothing defined for this, try the parent.
3940 // E.g. we may be a button loaded from a resource, with no callback function
3941 // defined.
3942 void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
3943 {
3944 if (GetEventHandler()->ProcessEvent(event) )
3945 return;
3946 if (m_windowParent)
3947 m_windowParent->GetEventHandler()->OnCommand(win, event);
3948 }
3949
3950 void wxWindow::SetConstraints(wxLayoutConstraints *c)
3951 {
3952 if (m_constraints)
3953 {
3954 UnsetConstraints(m_constraints);
3955 delete m_constraints;
3956 }
3957 m_constraints = c;
3958 if (m_constraints)
3959 {
3960 // Make sure other windows know they're part of a 'meaningful relationship'
3961 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
3962 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3963 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
3964 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3965 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
3966 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3967 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
3968 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3969 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
3970 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3971 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
3972 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3973 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
3974 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3975 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
3976 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3977 }
3978 }
3979
3980 // This removes any dangling pointers to this window
3981 // in other windows' constraintsInvolvedIn lists.
3982 void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
3983 {
3984 if (c)
3985 {
3986 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3987 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3988 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3989 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3990 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
3991 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3992 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
3993 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3994 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
3995 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3996 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
3997 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3998 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
3999 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4000 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
4001 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4002 }
4003 }
4004
4005 // Back-pointer to other windows we're involved with, so if we delete
4006 // this window, we must delete any constraints we're involved with.
4007 void wxWindow::AddConstraintReference(wxWindow *otherWin)
4008 {
4009 if (!m_constraintsInvolvedIn)
4010 m_constraintsInvolvedIn = new wxList;
4011 if (!m_constraintsInvolvedIn->Member(otherWin))
4012 m_constraintsInvolvedIn->Append(otherWin);
4013 }
4014
4015 // REMOVE back-pointer to other windows we're involved with.
4016 void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
4017 {
4018 if (m_constraintsInvolvedIn)
4019 m_constraintsInvolvedIn->DeleteObject(otherWin);
4020 }
4021
4022 // Reset any constraints that mention this window
4023 void wxWindow::DeleteRelatedConstraints(void)
4024 {
4025 if (m_constraintsInvolvedIn)
4026 {
4027 wxNode *node = m_constraintsInvolvedIn->First();
4028 while (node)
4029 {
4030 wxWindow *win = (wxWindow *)node->Data();
4031 wxNode *next = node->Next();
4032 wxLayoutConstraints *constr = win->GetConstraints();
4033
4034 // Reset any constraints involving this window
4035 if (constr)
4036 {
4037 constr->left.ResetIfWin((wxWindow *)this);
4038 constr->top.ResetIfWin((wxWindow *)this);
4039 constr->right.ResetIfWin((wxWindow *)this);
4040 constr->bottom.ResetIfWin((wxWindow *)this);
4041 constr->width.ResetIfWin((wxWindow *)this);
4042 constr->height.ResetIfWin((wxWindow *)this);
4043 constr->centreX.ResetIfWin((wxWindow *)this);
4044 constr->centreY.ResetIfWin((wxWindow *)this);
4045 }
4046 delete node;
4047 node = next;
4048 }
4049 delete m_constraintsInvolvedIn;
4050 m_constraintsInvolvedIn = NULL;
4051 }
4052 }
4053
4054 void wxWindow::SetSizer(wxSizer *sizer)
4055 {
4056 m_windowSizer = sizer;
4057 if (sizer)
4058 sizer->SetSizerParent((wxWindow *)this);
4059 }
4060
4061 /*
4062 * New version
4063 */
4064
4065 bool wxWindow::Layout(void)
4066 {
4067 if (GetConstraints())
4068 {
4069 int w, h;
4070 GetClientSize(&w, &h);
4071 GetConstraints()->width.SetValue(w);
4072 GetConstraints()->height.SetValue(h);
4073 }
4074
4075 // If top level (one sizer), evaluate the sizer's constraints.
4076 if (GetSizer())
4077 {
4078 int noChanges;
4079 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
4080 GetSizer()->LayoutPhase1(&noChanges);
4081 GetSizer()->LayoutPhase2(&noChanges);
4082 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
4083 return TRUE;
4084 }
4085 else
4086 {
4087 // Otherwise, evaluate child constraints
4088 ResetConstraints(); // Mark all constraints as unevaluated
4089 DoPhase(1); // Just one phase need if no sizers involved
4090 DoPhase(2);
4091 SetConstraintSizes(); // Recursively set the real window sizes
4092 }
4093 return TRUE;
4094 }
4095
4096
4097 // Do a phase of evaluating constraints:
4098 // the default behaviour. wxSizers may do a similar
4099 // thing, but also impose their own 'constraints'
4100 // and order the evaluation differently.
4101 bool wxWindow::LayoutPhase1(int *noChanges)
4102 {
4103 wxLayoutConstraints *constr = GetConstraints();
4104 if (constr)
4105 {
4106 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
4107 }
4108 else
4109 return TRUE;
4110 }
4111
4112 bool wxWindow::LayoutPhase2(int *noChanges)
4113 {
4114 *noChanges = 0;
4115
4116 // Layout children
4117 DoPhase(1);
4118 DoPhase(2);
4119 return TRUE;
4120 }
4121
4122 // Do a phase of evaluating child constraints
4123 bool wxWindow::DoPhase(const int phase)
4124 {
4125 int noIterations = 0;
4126 int maxIterations = 500;
4127 int noChanges = 1;
4128 int noFailures = 0;
4129 wxList succeeded;
4130 while ((noChanges > 0) && (noIterations < maxIterations))
4131 {
4132 noChanges = 0;
4133 noFailures = 0;
4134 wxNode *node = GetChildren()->First();
4135 while (node)
4136 {
4137 wxWindow *child = (wxWindow *)node->Data();
4138 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
4139 {
4140 wxLayoutConstraints *constr = child->GetConstraints();
4141 if (constr)
4142 {
4143 if (succeeded.Member(child))
4144 {
4145 }
4146 else
4147 {
4148 int tempNoChanges = 0;
4149 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
4150 noChanges += tempNoChanges;
4151 if (success)
4152 {
4153 succeeded.Append(child);
4154 }
4155 }
4156 }
4157 }
4158 node = node->Next();
4159 }
4160 noIterations ++;
4161 }
4162 return TRUE;
4163 }
4164
4165 void wxWindow::ResetConstraints(void)
4166 {
4167 wxLayoutConstraints *constr = GetConstraints();
4168 if (constr)
4169 {
4170 constr->left.SetDone(FALSE);
4171 constr->top.SetDone(FALSE);
4172 constr->right.SetDone(FALSE);
4173 constr->bottom.SetDone(FALSE);
4174 constr->width.SetDone(FALSE);
4175 constr->height.SetDone(FALSE);
4176 constr->centreX.SetDone(FALSE);
4177 constr->centreY.SetDone(FALSE);
4178 }
4179 wxNode *node = GetChildren()->First();
4180 while (node)
4181 {
4182 wxWindow *win = (wxWindow *)node->Data();
4183 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
4184 win->ResetConstraints();
4185 node = node->Next();
4186 }
4187 }
4188
4189 // Need to distinguish between setting the 'fake' size for
4190 // windows and sizers, and setting the real values.
4191 void wxWindow::SetConstraintSizes(const bool recurse)
4192 {
4193 wxLayoutConstraints *constr = GetConstraints();
4194 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
4195 constr->width.GetDone() && constr->height.GetDone())
4196 {
4197 int x = constr->left.GetValue();
4198 int y = constr->top.GetValue();
4199 int w = constr->width.GetValue();
4200 int h = constr->height.GetValue();
4201
4202 // If we don't want to resize this window, just move it...
4203 if ((constr->width.GetRelationship() != wxAsIs) ||
4204 (constr->height.GetRelationship() != wxAsIs))
4205 {
4206 // Calls Layout() recursively. AAAGH. How can we stop that.
4207 // Simply take Layout() out of non-top level OnSizes.
4208 SizerSetSize(x, y, w, h);
4209 }
4210 else
4211 {
4212 SizerMove(x, y);
4213 }
4214 }
4215 else if (constr)
4216 {
4217 char *windowClass = this->GetClassInfo()->GetClassName();
4218
4219 wxString winName;
4220 if (GetName() == "")
4221 winName = "unnamed";
4222 else
4223 winName = GetName();
4224 wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
4225 if (!constr->left.GetDone())
4226 wxDebugMsg(" unsatisfied 'left' constraint.\n");
4227 if (!constr->right.GetDone())
4228 wxDebugMsg(" unsatisfied 'right' constraint.\n");
4229 if (!constr->width.GetDone())
4230 wxDebugMsg(" unsatisfied 'width' constraint.\n");
4231 if (!constr->height.GetDone())
4232 wxDebugMsg(" unsatisfied 'height' constraint.\n");
4233 wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
4234 }
4235
4236 if (recurse)
4237 {
4238 wxNode *node = GetChildren()->First();
4239 while (node)
4240 {
4241 wxWindow *win = (wxWindow *)node->Data();
4242 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
4243 win->SetConstraintSizes();
4244 node = node->Next();
4245 }
4246 }
4247 }
4248
4249 // This assumes that all sizers are 'on' the same
4250 // window, i.e. the parent of this window.
4251 void wxWindow::TransformSizerToActual(int *x, int *y) const
4252 {
4253 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
4254 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
4255 return;
4256
4257 int xp, yp;
4258 m_sizerParent->GetPosition(&xp, &yp);
4259 m_sizerParent->TransformSizerToActual(&xp, &yp);
4260 *x += xp;
4261 *y += yp;
4262 }
4263
4264 void wxWindow::SizerSetSize(const int x, const int y, const int w, const int h)
4265 {
4266 int xx = x;
4267 int yy = y;
4268 TransformSizerToActual(&xx, &yy);
4269 SetSize(xx, yy, w, h);
4270 }
4271
4272 void wxWindow::SizerMove(const int x, const int y)
4273 {
4274 int xx = x;
4275 int yy = y;
4276 TransformSizerToActual(&xx, &yy);
4277 Move(xx, yy);
4278 }
4279
4280 // Only set the size/position of the constraint (if any)
4281 void wxWindow::SetSizeConstraint(const int x, const int y, const int w, const int h)
4282 {
4283 wxLayoutConstraints *constr = GetConstraints();
4284 if (constr)
4285 {
4286 if (x != -1)
4287 {
4288 constr->left.SetValue(x);
4289 constr->left.SetDone(TRUE);
4290 }
4291 if (y != -1)
4292 {
4293 constr->top.SetValue(y);
4294 constr->top.SetDone(TRUE);
4295 }
4296 if (w != -1)
4297 {
4298 constr->width.SetValue(w);
4299 constr->width.SetDone(TRUE);
4300 }
4301 if (h != -1)
4302 {
4303 constr->height.SetValue(h);
4304 constr->height.SetDone(TRUE);
4305 }
4306 }
4307 }
4308
4309 void wxWindow::MoveConstraint(const int x, const int y)
4310 {
4311 wxLayoutConstraints *constr = GetConstraints();
4312 if (constr)
4313 {
4314 if (x != -1)
4315 {
4316 constr->left.SetValue(x);
4317 constr->left.SetDone(TRUE);
4318 }
4319 if (y != -1)
4320 {
4321 constr->top.SetValue(y);
4322 constr->top.SetDone(TRUE);
4323 }
4324 }
4325 }
4326
4327 void wxWindow::GetSizeConstraint(int *w, int *h) const
4328 {
4329 wxLayoutConstraints *constr = GetConstraints();
4330 if (constr)
4331 {
4332 *w = constr->width.GetValue();
4333 *h = constr->height.GetValue();
4334 }
4335 else
4336 GetSize(w, h);
4337 }
4338
4339 void wxWindow::GetClientSizeConstraint(int *w, int *h) const
4340 {
4341 wxLayoutConstraints *constr = GetConstraints();
4342 if (constr)
4343 {
4344 *w = constr->width.GetValue();
4345 *h = constr->height.GetValue();
4346 }
4347 else
4348 GetClientSize(w, h);
4349 }
4350
4351 void wxWindow::GetPositionConstraint(int *x, int *y) const
4352 {
4353 wxLayoutConstraints *constr = GetConstraints();
4354 if (constr)
4355 {
4356 *x = constr->left.GetValue();
4357 *y = constr->top.GetValue();
4358 }
4359 else
4360 GetPosition(x, y);
4361 }
4362
4363 bool wxWindow::Close(const bool force)
4364 {
4365 // Let's generalise it to work the same for any window.
4366 /*
4367 if (!IsKindOf(CLASSINFO(wxDialog)) && !IsKindOf(CLASSINFO(wxFrame)))
4368 {
4369 this->Destroy();
4370 return TRUE;
4371 }
4372 */
4373
4374 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
4375 event.SetEventObject(this);
4376 event.SetForce(force);
4377
4378 return GetEventHandler()->ProcessEvent(event);
4379
4380 /*
4381 if ( !force && event.GetVeto() )
4382 return FALSE;
4383
4384 Show(FALSE);
4385
4386 if (!wxPendingDelete.Member(this))
4387 wxPendingDelete.Append(this);
4388
4389 return TRUE;
4390 */
4391 }
4392
4393 wxObject* wxWindow::GetChild(const int number) const
4394 {
4395 // Return a pointer to the Nth object in the Panel
4396 if (!GetChildren())
4397 return(NULL) ;
4398 wxNode *node = GetChildren()->First();
4399 int n = number;
4400 while (node && n--)
4401 node = node->Next() ;
4402 if (node)
4403 {
4404 wxObject *obj = (wxObject *)node->Data();
4405 return(obj) ;
4406 }
4407 else
4408 return NULL ;
4409 }
4410
4411 void wxWindow::OnDefaultAction(wxControl *initiatingItem)
4412 {
4413 if (initiatingItem->IsKindOf(CLASSINFO(wxListBox)) && initiatingItem->GetCallback())
4414 {
4415 wxListBox *lbox = (wxListBox *)initiatingItem;
4416 wxCommandEvent event(wxEVENT_TYPE_LISTBOX_DCLICK_COMMAND);
4417 event.m_commandInt = -1;
4418 if ((lbox->GetWindowStyleFlag() & wxLB_MULTIPLE) == 0)
4419 {
4420 event.m_commandString = copystring(lbox->GetStringSelection());
4421 event.m_commandInt = lbox->GetSelection();
4422 event.m_clientData = lbox->wxListBox::GetClientData(event.m_commandInt);
4423 }
4424 event.m_eventObject = lbox;
4425
4426 lbox->ProcessCommand(event);
4427
4428 if (event.m_commandString)
4429 delete[] event.m_commandString;
4430 return;
4431 }
4432
4433 wxButton *but = GetDefaultItem();
4434 if (but)
4435 {
4436 wxCommandEvent event(wxEVENT_TYPE_BUTTON_COMMAND);
4437 but->Command(event);
4438 }
4439 }
4440
4441 void wxWindow::Clear(void)
4442 {
4443 wxClientDC dc(this);
4444 wxBrush brush(GetBackgroundColour(), wxSOLID);
4445 dc.SetBackground(brush);
4446 dc.Clear();
4447 }
4448
4449 // Fits the panel around the items
4450 void wxWindow::Fit(void)
4451 {
4452 int maxX = 0;
4453 int maxY = 0;
4454 wxNode *node = GetChildren()->First();
4455 while ( node )
4456 {
4457 wxWindow *win = (wxWindow *)node->Data();
4458 int wx, wy, ww, wh;
4459 win->GetPosition(&wx, &wy);
4460 win->GetSize(&ww, &wh);
4461 if ( wx + ww > maxX )
4462 maxX = wx + ww;
4463 if ( wy + wh > maxY )
4464 maxY = wy + wh;
4465
4466 node = node->Next();
4467 }
4468 SetClientSize(maxX + 5, maxY + 5);
4469 }
4470
4471 void wxWindow::SetValidator(const wxValidator& validator)
4472 {
4473 if ( m_windowValidator )
4474 delete m_windowValidator;
4475 m_windowValidator = validator.Clone();
4476
4477 if ( m_windowValidator )
4478 m_windowValidator->SetWindow(this) ;
4479 }
4480
4481 // Find a window by id or name
4482 wxWindow *wxWindow::FindWindow(const long id)
4483 {
4484 if ( GetId() == id)
4485 return this;
4486
4487 wxNode *node = GetChildren()->First();
4488 while ( node )
4489 {
4490 wxWindow *child = (wxWindow *)node->Data();
4491 wxWindow *found = child->FindWindow(id);
4492 if ( found )
4493 return found;
4494 node = node->Next();
4495 }
4496 return NULL;
4497 }
4498
4499 wxWindow *wxWindow::FindWindow(const wxString& name)
4500 {
4501 if ( GetName() == name)
4502 return this;
4503
4504 wxNode *node = GetChildren()->First();
4505 while ( node )
4506 {
4507 wxWindow *child = (wxWindow *)node->Data();
4508 wxWindow *found = child->FindWindow(name);
4509 if ( found )
4510 return found;
4511 node = node->Next();
4512 }
4513 return NULL;
4514 }
4515
4516 /* TODO
4517 // Default input behaviour for a scrolling canvas should be to scroll
4518 // according to the cursor keys pressed
4519 void wxWindow::OnChar(wxKeyEvent& event)
4520 {
4521 int x_page = 0;
4522 int y_page = 0;
4523 int start_x = 0;
4524 int start_y = 0;
4525 // Bugfix Begin
4526 int v_width = 0;
4527 int v_height = 0;
4528 int y_pages = 0;
4529 // Bugfix End
4530
4531 GetScrollUnitsPerPage(&x_page, &y_page);
4532 // Bugfix Begin
4533 GetVirtualSize(&v_width,&v_height);
4534 // Bugfix End
4535 ViewStart(&start_x, &start_y);
4536 // Bugfix begin
4537 if (vert_units)
4538 y_pages = (int)(v_height/vert_units) - y_page;
4539
4540 #ifdef __WINDOWS__
4541 int y = 0;
4542 #else
4543 int y = y_page-1;
4544 #endif
4545 // Bugfix End
4546 switch (event.keyCode)
4547 {
4548 case WXK_PRIOR:
4549 {
4550 // BugFix Begin
4551 if (y_page > 0)
4552 {
4553 if (start_y - y_page > 0)
4554 Scroll(start_x, start_y - y_page);
4555 else
4556 Scroll(start_x, 0);
4557 }
4558 // Bugfix End
4559 break;
4560 }
4561 case WXK_NEXT:
4562 {
4563 // Bugfix Begin
4564 if ((y_page > 0) && (start_y <= y_pages-y-1))
4565 {
4566 if (y_pages + y < start_y + y_page)
4567 Scroll(start_x, y_pages + y);
4568 else
4569 Scroll(start_x, start_y + y_page);
4570 }
4571 // Bugfix End
4572 break;
4573 }
4574 case WXK_UP:
4575 {
4576 if ((y_page > 0) && (start_y >= 1))
4577 Scroll(start_x, start_y - 1);
4578 break;
4579 }
4580 case WXK_DOWN:
4581 {
4582 // Bugfix Begin
4583 if ((y_page > 0) && (start_y <= y_pages-y-1))
4584 // Bugfix End
4585 {
4586 Scroll(start_x, start_y + 1);
4587 }
4588 break;
4589 }
4590 case WXK_LEFT:
4591 {
4592 if ((x_page > 0) && (start_x >= 1))
4593 Scroll(start_x - 1, start_y);
4594 break;
4595 }
4596 case WXK_RIGHT:
4597 {
4598 if (x_page > 0)
4599 Scroll(start_x + 1, start_y);
4600 break;
4601 }
4602 case WXK_HOME:
4603 {
4604 Scroll(0, 0);
4605 break;
4606 }
4607 // This is new
4608 case WXK_END:
4609 {
4610 Scroll(start_x, y_pages+y);
4611 break;
4612 }
4613 // end
4614 }
4615 }
4616 */
4617
4618 // Setup background and foreground colours correctly
4619 void wxWindow::SetupColours(void)
4620 {
4621 if (GetParent())
4622 SetBackgroundColour(GetParent()->GetBackgroundColour());
4623 }
4624
4625 // Do Update UI processing for child controls
4626
4627 // TODO: should this be implemented for the child window rather
4628 // than the parent? Then you can override it e.g. for wxCheckBox
4629 // to do the Right Thing rather than having to assume a fixed number
4630 // of control classes.
4631
4632 void wxWindow::UpdateWindowUI(void)
4633 {
4634 wxWindowID id = GetId();
4635 if (id > 0)
4636 {
4637 wxUpdateUIEvent event(id);
4638 event.m_eventObject = this;
4639
4640 if (this->GetEventHandler()->ProcessEvent(event))
4641 {
4642 if (event.GetSetEnabled())
4643 this->Enable(event.GetEnabled());
4644
4645 if (event.GetSetText() && this->IsKindOf(CLASSINFO(wxControl)))
4646 ((wxControl*)this)->SetLabel(event.GetText());
4647
4648 if (this->IsKindOf(CLASSINFO(wxCheckBox)))
4649 {
4650 if (event.GetSetChecked())
4651 ((wxCheckBox *) this)->SetValue(event.GetChecked());
4652 }
4653 else if (this->IsKindOf(CLASSINFO(wxRadioButton)))
4654 {
4655 if (event.GetSetChecked())
4656 ((wxRadioButton *) this)->SetValue(event.GetChecked());
4657 }
4658 }
4659 }
4660
4661 }
4662
4663 void wxWindow::OnIdle(wxIdleEvent& event)
4664 {
4665 // Check if we need to send a LEAVE event
4666 if (m_mouseInWindow)
4667 {
4668 POINT pt;
4669 ::GetCursorPos(&pt);
4670 if (::WindowFromPoint(pt) != (HWND) GetHWND())
4671 {
4672 // Generate a LEAVE event
4673 m_mouseInWindow = FALSE;
4674 MSWOnMouseLeave(pt.x, pt.y, 0);
4675 }
4676 }
4677 UpdateWindowUI();
4678 }
4679
4680 // Raise the window to the top of the Z order
4681 void wxWindow::Raise(void)
4682 {
4683 ::BringWindowToTop((HWND) GetHWND());
4684 }
4685
4686 // Lower the window to the bottom of the Z order
4687 void wxWindow::Lower(void)
4688 {
4689 ::SetWindowPos((HWND) GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
4690 }
4691