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