]> git.saurik.com Git - wxWidgets.git/blob - src/msw/window.cpp
added some wxMSW stuff
[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 wxRemoveHandleAssociation(this);
307
308 // TODO for backward compatibility
309 #if 0
310 // WX_CANVAS
311 if (m_windowDC)
312 {
313 HWND hWnd = (HWND) GetHWND();
314 HDC dc = ::GetDC(hWnd);
315 m_windowDC->SelectOldObjects (dc);
316 ReleaseDC(hWnd, dc);
317 delete m_windowDC;
318 }
319 #endif
320
321 if (m_windowParent)
322 m_windowParent->RemoveChild(this);
323
324 DestroyChildren();
325
326 if (m_hWnd)
327 ::DestroyWindow((HWND)m_hWnd);
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 DELETEP(m_pDropTarget);
570 m_pDropTarget = pDropTarget;
571 if ( m_pDropTarget != 0 )
572 m_pDropTarget->Register(m_hWnd);
573 }
574
575 #endif
576
577 //old style file-manager drag&drop support
578 // I think we should retain the old-style
579 // DragAcceptFiles in parallel with SetDropTarget.
580 // JACS
581 void wxWindow::DragAcceptFiles(const bool accept)
582 {
583 HWND hWnd = (HWND) GetHWND();
584 if (hWnd)
585 ::DragAcceptFiles(hWnd, (BOOL)accept);
586 }
587
588 // Get total size
589 void wxWindow::GetSize(int *x, int *y) const
590 {
591 HWND hWnd = (HWND) GetHWND();
592 RECT rect;
593 GetWindowRect(hWnd, &rect);
594 *x = rect.right - rect.left;
595 *y = rect.bottom - rect.top;
596 }
597
598 void wxWindow::GetPosition(int *x, int *y) const
599 {
600 HWND hWnd = (HWND) GetHWND();
601 HWND hParentWnd = 0;
602 if (GetParent())
603 hParentWnd = (HWND) GetParent()->GetHWND();
604
605 RECT rect;
606 GetWindowRect(hWnd, &rect);
607
608 // Since we now have the absolute screen coords,
609 // if there's a parent we must subtract its top left corner
610 POINT point;
611 point.x = rect.left;
612 point.y = rect.top;
613 if (hParentWnd)
614 {
615 ::ScreenToClient(hParentWnd, &point);
616 }
617 *x = point.x;
618 *y = point.y;
619 }
620
621 void wxWindow::ScreenToClient(int *x, int *y) const
622 {
623 HWND hWnd = (HWND) GetHWND();
624 POINT pt;
625 pt.x = *x;
626 pt.y = *y;
627 ::ScreenToClient(hWnd, &pt);
628
629 *x = pt.x;
630 *y = pt.y;
631 }
632
633 void wxWindow::ClientToScreen(int *x, int *y) const
634 {
635 HWND hWnd = (HWND) GetHWND();
636 POINT pt;
637 pt.x = *x;
638 pt.y = *y;
639 ::ClientToScreen(hWnd, &pt);
640
641 *x = pt.x;
642 *y = pt.y;
643 }
644
645 void wxWindow::SetCursor(const wxCursor& cursor)
646 {
647 m_windowCursor = cursor;
648 if (m_windowCursor.Ok())
649 {
650 HWND hWnd = (HWND) GetHWND();
651
652 // Change the cursor NOW if we're within the correct window
653 POINT point;
654 ::GetCursorPos(&point);
655
656 RECT rect;
657 ::GetWindowRect(hWnd, &rect);
658
659 if (::PtInRect(&rect, point) && !wxIsBusy())
660 ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
661 }
662
663 // This will cause big reentrancy problems if wxFlushEvents is implemented.
664 // wxFlushEvents();
665 // return old_cursor;
666 }
667
668
669 // Get size *available for subwindows* i.e. excluding menu bar etc.
670 // For XView, this is the same as GetSize
671 void wxWindow::GetClientSize(int *x, int *y) const
672 {
673 HWND hWnd = (HWND) GetHWND();
674 RECT rect;
675 GetClientRect(hWnd, &rect);
676 *x = rect.right;
677 *y = rect.bottom;
678 }
679
680 void wxWindow::SetSize(const int x, const int y, const int width, const int height, const int sizeFlags)
681 {
682 int currentX, currentY;
683 GetPosition(&currentX, &currentY);
684 int actualWidth = width;
685 int actualHeight = height;
686 int actualX = x;
687 int actualY = y;
688 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
689 actualX = currentX;
690 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
691 actualY = currentY;
692
693 int currentW,currentH;
694 GetSize(&currentW, &currentH);
695 if (width == -1)
696 actualWidth = currentW ;
697 if (height == -1)
698 actualHeight = currentH ;
699
700 HWND hWnd = (HWND) GetHWND();
701 if (hWnd)
702 MoveWindow(hWnd, actualX, actualY, actualWidth, actualHeight, (BOOL)TRUE);
703
704 /* Not needed? should be called anyway via MoveWindow
705 if (!(width == -1) && (height == -1))
706 {
707 #if WXWIN_COMPATIBILITY
708 GetEventHandler()->OldOnSize(width, height);
709 #else
710 wxSizeEvent event(wxSize(width, height), m_windowId);
711 event.eventObject = this;
712 GetEventHandler()->ProcessEvent(event);
713 #endif
714 }
715 */
716 }
717
718 void wxWindow::SetClientSize(const int width, const int height)
719 {
720 wxWindow *parent = GetParent();
721 HWND hWnd = (HWND) GetHWND();
722 HWND hParentWnd = (HWND) (HWND) parent->GetHWND();
723
724 RECT rect;
725 GetClientRect(hWnd, &rect);
726
727 RECT rect2;
728 GetWindowRect(hWnd, &rect2);
729
730 // Find the difference between the entire window (title bar and all)
731 // and the client area; add this to the new client size to move the
732 // window
733 int actual_width = rect2.right - rect2.left - rect.right + width;
734 int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
735
736 // If there's a parent, must subtract the parent's top left corner
737 // since MoveWindow moves relative to the parent
738
739 POINT point;
740 point.x = rect2.left;
741 point.y = rect2.top;
742 if (parent)
743 {
744 ::ScreenToClient(hParentWnd, &point);
745 }
746
747 MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
748 #if WXWIN_COMPATIBILITY
749 GetEventHandler()->OldOnSize(width, height);
750 #else
751 wxSizeEvent event(wxSize(width, height), m_windowId);
752 event.m_eventObject = this;
753 GetEventHandler()->ProcessEvent(event);
754 #endif
755 }
756
757 bool wxWindow::Show(const bool show)
758 {
759 HWND hWnd = (HWND) GetHWND();
760 int cshow;
761 if (show)
762 cshow = SW_SHOW;
763 else
764 cshow = SW_HIDE;
765 ShowWindow(hWnd, (BOOL)cshow);
766 if (show)
767 {
768 BringWindowToTop(hWnd);
769 // Next line causes a crash on NT, apparently.
770 // UpdateWindow(hWnd); // Should this be here or will it cause inefficiency?
771 }
772 return TRUE;
773 }
774
775 bool wxWindow::IsShown(void) const
776 {
777 return (::IsWindowVisible((HWND) GetHWND()) != 0);
778 }
779
780 int wxWindow::GetCharHeight(void) const
781 {
782 TEXTMETRIC lpTextMetric;
783 HWND hWnd = (HWND) GetHWND();
784 HDC dc = ::GetDC(hWnd);
785
786 GetTextMetrics(dc, &lpTextMetric);
787 ::ReleaseDC(hWnd, dc);
788
789 return lpTextMetric.tmHeight;
790 }
791
792 int wxWindow::GetCharWidth(void) const
793 {
794 TEXTMETRIC lpTextMetric;
795 HWND hWnd = (HWND) GetHWND();
796 HDC dc = ::GetDC(hWnd);
797
798 GetTextMetrics(dc, &lpTextMetric);
799 ::ReleaseDC(hWnd, dc);
800
801 return lpTextMetric.tmAveCharWidth;
802 }
803
804 void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
805 int *descent, int *externalLeading, const wxFont *theFont, const bool) const
806 {
807 wxFont *fontToUse = (wxFont *)theFont;
808 if (!fontToUse)
809 fontToUse = (wxFont *) & m_windowFont;
810
811 HWND hWnd = (HWND) GetHWND();
812 HDC dc = ::GetDC(hWnd);
813
814 HFONT fnt = 0;
815 HFONT was = 0;
816 if (fontToUse && fontToUse->Ok())
817 {
818 // fontToUse->UseResource();
819
820 // fontToUse->RealizeResource();
821 if ((fnt=(HFONT) fontToUse->GetResourceHandle()))
822 was = SelectObject(dc,fnt) ;
823 }
824
825 SIZE sizeRect;
826 TEXTMETRIC tm;
827 GetTextExtentPoint(dc, (const char *)string, (int)string.Length(), &sizeRect);
828 GetTextMetrics(dc, &tm);
829
830 if (fontToUse && fnt && was)
831 SelectObject(dc,was) ;
832
833 ReleaseDC(hWnd, dc);
834
835 *x = sizeRect.cx;
836 *y = sizeRect.cy;
837 if (descent) *descent = tm.tmDescent;
838 if (externalLeading) *externalLeading = tm.tmExternalLeading;
839
840 // if (fontToUse)
841 // fontToUse->ReleaseResource();
842 }
843
844 #if WXWIN_COMPATIBILITY
845 void wxWindow::GetTextExtent(const wxString& string, float *x, float *y,
846 float *descent,
847 float *externalLeading,
848 const wxFont *theFont, const bool use16) const
849 {
850 int x1, y1, descent1, externalLeading1;
851 GetTextExtent(string, &x1, &y1, &descent1, &externalLeading1, theFont, use16);
852 *x = x1; *y = y1;
853 if ( descent )
854 *descent = descent1;
855 if ( externalLeading )
856 *externalLeading = externalLeading1;
857 }
858 #endif
859
860 void wxWindow::Refresh(const bool eraseBack, const wxRectangle *rect)
861 {
862 HWND hWnd = (HWND) GetHWND();
863 if (hWnd)
864 {
865 if (rect)
866 {
867 RECT mswRect;
868 mswRect.left = rect->x;
869 mswRect.top = rect->y;
870 mswRect.right = rect->x + rect->width;
871 mswRect.bottom = rect->y + rect->height;
872
873 ::InvalidateRect(hWnd, &mswRect, eraseBack);
874 }
875 else
876 ::InvalidateRect(hWnd, NULL, eraseBack);
877 }
878 }
879
880 // TODO: Are these really necessary now?
881 /*
882 WXHDC wxWindow::GetHDC(void) const
883 {
884 wxWindow *nonConst = (wxWindow *)this;
885 if (m_paintHDC)
886 return(m_paintHDC) ;
887 nonConst->m_tempHDC = (WXHDC) ::GetDC((HWND) GetHWND()) ;
888 return(m_tempHDC) ;
889 }
890
891 void wxWindow::ReleaseHDC(void)
892 {
893 // We're within an OnPaint: it'll be released.
894 if (m_paintHDC)
895 return ;
896
897 ::ReleaseDC((HWND) GetHWND(),(HDC) m_tempHDC) ;
898 }
899 */
900
901 // Hook for new window just as it's being created,
902 // when the window isn't yet associated with the handle
903 wxWindow *wxWndHook = NULL;
904
905 /*
906 #if HAVE_SOCKET
907 // DDE Interface Handler
908 extern "C" {
909 long ddeWindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam);
910 void __ddeUnblock(HWND hWnd, WPARAM wParam);
911 };
912 #endif
913 */
914
915 // Main Windows 3 window proc
916 LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
917 {
918 wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
919
920 if (!wnd && wxWndHook)
921 {
922 wxAssociateWinWithHandle(hWnd, wxWndHook);
923 wnd = wxWndHook;
924 wxWndHook = NULL;
925 wnd->m_hWnd = (WXHWND) hWnd;
926 }
927 #if (DEBUG > 1)
928 wxDebugMsg("hWnd = %d, m_hWnd = %d, msg = %d\n", hWnd, m_hWnd, message);
929 #endif
930 // Stop right here if we don't have a valid handle
931 // in our wxWnd object.
932 if (wnd && !wnd->m_hWnd) {
933 // wxDebugMsg("Warning: could not find a valid handle, wx_win.cc/wxWndProc.\n");
934 wnd->m_hWnd = (WXHWND) hWnd;
935 long res = wnd->MSWDefWindowProc(message, wParam, lParam );
936 wnd->m_hWnd = 0;
937 return res;
938 }
939
940 if (wnd) {
941 wnd->m_lastMsg = message;
942 wnd->m_lastWParam = wParam;
943 wnd->m_lastLParam = lParam;
944 /* Don't know why this was here
945 if (message == WM_SETFONT)
946 return 0;
947 else if (message == WM_INITDIALOG)
948 return TRUE;
949 */
950 }
951 if (wnd)
952 return wnd->MSWWindowProc(message, wParam, lParam);
953 else
954 return DefWindowProc( hWnd, message, wParam, lParam );
955 }
956
957 // Should probably have a test for 'genuine' NT
958 #if defined(__WIN32__)
959 #define DIMENSION_TYPE short
960 #else
961 #define DIMENSION_TYPE int
962 #endif
963
964 // Main Windows 3 window proc
965 long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
966 {
967 #if 0
968 switch (message)
969 {
970 case WM_INITDIALOG:
971 case WM_ACTIVATE:
972 case WM_SETFOCUS:
973 case WM_KILLFOCUS:
974 case WM_CREATE:
975 case WM_PAINT:
976 case WM_QUERYDRAGICON:
977 case WM_SIZE:
978 case WM_RBUTTONDOWN:
979 case WM_RBUTTONUP:
980 case WM_RBUTTONDBLCLK:
981 case WM_MBUTTONDOWN:
982 case WM_MBUTTONUP:
983 case WM_MBUTTONDBLCLK:
984 case WM_LBUTTONDOWN:
985 case WM_LBUTTONUP:
986 case WM_LBUTTONDBLCLK:
987 case WM_MOUSEMOVE:
988 // case WM_DESTROY:
989 case WM_COMMAND:
990 case WM_NOTIFY:
991 case WM_MENUSELECT:
992 case WM_INITMENUPOPUP:
993 case WM_DRAWITEM:
994 case WM_MEASUREITEM:
995 case WM_KEYDOWN:
996 case WM_KEYUP:
997 case WM_CHAR: // Always an ASCII character
998 case WM_HSCROLL:
999 case WM_VSCROLL:
1000 case WM_CTLCOLORBTN:
1001 case WM_CTLCOLORDLG:
1002 case WM_CTLCOLORLISTBOX:
1003 case WM_CTLCOLORMSGBOX:
1004 case WM_CTLCOLORSCROLLBAR:
1005 case WM_CTLCOLORSTATIC:
1006 case WM_CTLCOLOREDIT:
1007 case WM_SYSCOLORCHANGE:
1008 case WM_ERASEBKGND:
1009 case WM_MDIACTIVATE:
1010 case WM_DROPFILES:
1011 case WM_QUERYENDSESSION:
1012 // case WM_CLOSE:
1013 case WM_GETMINMAXINFO:
1014 return MSWDefWindowProc(message, wParam, lParam );
1015 }
1016 #endif
1017
1018
1019 HWND hWnd = (HWND)m_hWnd;
1020
1021 switch (message)
1022 {
1023 /*
1024 case WM_SETFONT:
1025 {
1026 return 0;
1027 }
1028 */
1029 case WM_ACTIVATE:
1030 {
1031 #ifdef __WIN32__
1032 WORD state = LOWORD(wParam);
1033 WORD minimized = HIWORD(wParam);
1034 HWND hwnd = (HWND)lParam;
1035 #else
1036 WORD state = (WORD)wParam;
1037 WORD minimized = LOWORD(lParam);
1038 HWND hwnd = (HWND)HIWORD(lParam);
1039 #endif
1040 MSWOnActivate(state, (minimized != 0), (WXHWND) hwnd);
1041 return 0;
1042 break;
1043 }
1044 case WM_SETFOCUS:
1045 {
1046 HWND hwnd = (HWND)wParam;
1047 // return OnSetFocus(hwnd);
1048
1049 if (MSWOnSetFocus((WXHWND) hwnd))
1050 return 0;
1051 else return MSWDefWindowProc(message, wParam, lParam );
1052 break;
1053 }
1054 case WM_KILLFOCUS:
1055 {
1056 HWND hwnd = (HWND)lParam;
1057 // return OnKillFocus(hwnd);
1058 if (MSWOnKillFocus((WXHWND) hwnd))
1059 return 0;
1060 else
1061 return MSWDefWindowProc(message, wParam, lParam );
1062 break;
1063 }
1064 case WM_CREATE:
1065 {
1066 MSWOnCreate((WXLPCREATESTRUCT) (LPCREATESTRUCT)lParam);
1067 return 0;
1068 break;
1069 }
1070 case WM_SHOWWINDOW:
1071 {
1072 MSWOnShow((wParam != 0), (int) lParam);
1073 break;
1074 }
1075 case WM_PAINT:
1076 {
1077 if (MSWOnPaint())
1078 return 0;
1079 else return MSWDefWindowProc(message, wParam, lParam );
1080 break;
1081 }
1082 case WM_QUERYDRAGICON:
1083 {
1084 HICON hIcon = 0;
1085 if ((hIcon = (HICON) MSWOnQueryDragIcon()))
1086 return (long)hIcon;
1087 else return MSWDefWindowProc(message, wParam, lParam );
1088 break;
1089 }
1090
1091 case WM_SIZE:
1092 {
1093 int width = LOWORD(lParam);
1094 int height = HIWORD(lParam);
1095 MSWOnSize(width, height, wParam);
1096 break;
1097 }
1098
1099 case WM_WINDOWPOSCHANGING:
1100 {
1101 WINDOWPOS *pos = (WINDOWPOS *)lParam;
1102 MSWOnWindowPosChanging((void *)pos);
1103 break;
1104 }
1105
1106 case WM_RBUTTONDOWN:
1107 {
1108 int x = (DIMENSION_TYPE) LOWORD(lParam);
1109 int y = (DIMENSION_TYPE) HIWORD(lParam);
1110 MSWOnRButtonDown(x, y, wParam);
1111 break;
1112 }
1113 case WM_RBUTTONUP:
1114 {
1115 int x = (DIMENSION_TYPE) LOWORD(lParam);
1116 int y = (DIMENSION_TYPE) HIWORD(lParam);
1117 MSWOnRButtonUp(x, y, wParam);
1118 break;
1119 }
1120 case WM_RBUTTONDBLCLK:
1121 {
1122 int x = (DIMENSION_TYPE) LOWORD(lParam);
1123 int y = (DIMENSION_TYPE) HIWORD(lParam);
1124 MSWOnRButtonDClick(x, y, wParam);
1125 break;
1126 }
1127 case WM_MBUTTONDOWN:
1128 {
1129 int x = (DIMENSION_TYPE) LOWORD(lParam);
1130 int y = (DIMENSION_TYPE) HIWORD(lParam);
1131 MSWOnMButtonDown(x, y, wParam);
1132 break;
1133 }
1134 case WM_MBUTTONUP:
1135 {
1136 int x = (DIMENSION_TYPE) LOWORD(lParam);
1137 int y = (DIMENSION_TYPE) HIWORD(lParam);
1138 MSWOnMButtonUp(x, y, wParam);
1139 break;
1140 }
1141 case WM_MBUTTONDBLCLK:
1142 {
1143 int x = (DIMENSION_TYPE) LOWORD(lParam);
1144 int y = (DIMENSION_TYPE) HIWORD(lParam);
1145 MSWOnMButtonDClick(x, y, wParam);
1146 break;
1147 }
1148 case WM_LBUTTONDOWN:
1149 {
1150 int x = (DIMENSION_TYPE) LOWORD(lParam);
1151 int y = (DIMENSION_TYPE) HIWORD(lParam);
1152 MSWOnLButtonDown(x, y, wParam);
1153 break;
1154 }
1155 case WM_LBUTTONUP:
1156 {
1157 int x = (DIMENSION_TYPE) LOWORD(lParam);
1158 int y = (DIMENSION_TYPE) HIWORD(lParam);
1159 MSWOnLButtonUp(x, y, wParam);
1160 break;
1161 }
1162 case WM_LBUTTONDBLCLK:
1163 {
1164 int x = (DIMENSION_TYPE) LOWORD(lParam);
1165 int y = (DIMENSION_TYPE) HIWORD(lParam);
1166 MSWOnLButtonDClick(x, y, wParam);
1167 break;
1168 }
1169 case WM_MOUSEMOVE:
1170 {
1171 int x = (DIMENSION_TYPE) LOWORD(lParam);
1172 int y = (DIMENSION_TYPE) HIWORD(lParam);
1173 MSWOnMouseMove(x, y, wParam);
1174 break;
1175 }
1176 case MM_JOY1BUTTONDOWN:
1177 {
1178 int x = LOWORD(lParam);
1179 int y = HIWORD(lParam);
1180 MSWOnJoyDown(wxJOYSTICK1, x, y, wParam);
1181 break;
1182 }
1183 case MM_JOY2BUTTONDOWN:
1184 {
1185 int x = LOWORD(lParam);
1186 int y = HIWORD(lParam);
1187 MSWOnJoyDown(wxJOYSTICK2, x, y, wParam);
1188 break;
1189 }
1190 case MM_JOY1BUTTONUP:
1191 {
1192 int x = LOWORD(lParam);
1193 int y = HIWORD(lParam);
1194 MSWOnJoyUp(wxJOYSTICK1, x, y, wParam);
1195 break;
1196 }
1197 case MM_JOY2BUTTONUP:
1198 {
1199 int x = LOWORD(lParam);
1200 int y = HIWORD(lParam);
1201 MSWOnJoyUp(wxJOYSTICK2, x, y, wParam);
1202 break;
1203 }
1204 case MM_JOY1MOVE:
1205 {
1206 int x = LOWORD(lParam);
1207 int y = HIWORD(lParam);
1208 MSWOnJoyMove(wxJOYSTICK1, x, y, wParam);
1209 break;
1210 }
1211 case MM_JOY2MOVE:
1212 {
1213 int x = LOWORD(lParam);
1214 int y = HIWORD(lParam);
1215 MSWOnJoyMove(wxJOYSTICK2, x, y, wParam);
1216 break;
1217 }
1218 case MM_JOY1ZMOVE:
1219 {
1220 int z = LOWORD(lParam);
1221 MSWOnJoyZMove(wxJOYSTICK1, z, wParam);
1222 break;
1223 }
1224 case MM_JOY2ZMOVE:
1225 {
1226 int z = LOWORD(lParam);
1227 MSWOnJoyZMove(wxJOYSTICK2, z, wParam);
1228 break;
1229 }
1230 case WM_DESTROY:
1231 {
1232 if (MSWOnDestroy())
1233 return 0;
1234 else return MSWDefWindowProc(message, wParam, lParam );
1235 break;
1236 }
1237 case WM_SYSCOMMAND:
1238 {
1239 return MSWOnSysCommand(wParam, lParam);
1240 break;
1241 }
1242 case WM_COMMAND:
1243 {
1244 #ifdef __WIN32__
1245 WORD id = LOWORD(wParam);
1246 HWND hwnd = (HWND)lParam;
1247 WORD cmd = HIWORD(wParam);
1248 #else
1249 WORD id = (WORD)wParam;
1250 HWND hwnd = (HWND)LOWORD(lParam) ;
1251 WORD cmd = HIWORD(lParam);
1252 #endif
1253 if (!MSWOnCommand(id, cmd, (WXHWND) hwnd))
1254 return MSWDefWindowProc(message, wParam, lParam );
1255 break;
1256 }
1257 #if defined(__WIN95__)
1258 case WM_NOTIFY:
1259 {
1260 if (!MSWOnNotify(wParam, lParam))
1261 return MSWDefWindowProc(message, wParam, lParam );
1262 break;
1263 }
1264 #endif
1265 case WM_MENUSELECT:
1266 {
1267 #ifdef __WIN32__
1268 WORD flags = HIWORD(wParam);
1269 HMENU sysmenu = (HMENU)lParam;
1270 #else
1271 WORD flags = LOWORD(lParam);
1272 HMENU sysmenu = (HMENU)HIWORD(lParam);
1273 #endif
1274 MSWOnMenuHighlight((WORD)wParam, flags, (WXHMENU) sysmenu);
1275 break;
1276 }
1277 case WM_INITMENUPOPUP:
1278 {
1279 MSWOnInitMenuPopup((WXHMENU) (HMENU)wParam, (int)LOWORD(lParam), (HIWORD(lParam) != 0));
1280 break;
1281 }
1282 case WM_DRAWITEM:
1283 {
1284 return MSWOnDrawItem((int)wParam, (WXDRAWITEMSTRUCT *)lParam);
1285 break;
1286 }
1287 case WM_MEASUREITEM:
1288 {
1289 return MSWOnMeasureItem((int)wParam, (WXMEASUREITEMSTRUCT *)lParam);
1290 break;
1291 }
1292 case WM_KEYDOWN:
1293 {
1294 // return Default();
1295
1296 if (wParam == VK_SHIFT)
1297 return Default();
1298
1299 else if (wParam == VK_CONTROL)
1300 return Default();
1301
1302 // Avoid duplicate messages to OnChar
1303 else if ((wParam != VK_ESCAPE) && (wParam != VK_SPACE) && (wParam != VK_RETURN) && (wParam != VK_BACK) && (wParam != VK_TAB))
1304 {
1305 MSWOnChar((WORD)wParam, lParam);
1306 if (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE)
1307 return Default();
1308 }
1309 else
1310 return Default();
1311 break;
1312 }
1313 case WM_KEYUP:
1314 {
1315 /*
1316 if (wParam == VK_SHIFT)
1317 wxShiftDown = FALSE;
1318 else if (wParam == VK_CONTROL)
1319 wxControlDown = FALSE;
1320 */
1321 break;
1322 }
1323 case WM_CHAR: // Always an ASCII character
1324 {
1325 MSWOnChar((WORD)wParam, lParam, TRUE);
1326 break;
1327 }
1328 case WM_HSCROLL:
1329 {
1330 #ifdef __WIN32__
1331 WORD code = LOWORD(wParam);
1332 WORD pos = HIWORD(wParam);
1333 HWND control = (HWND)lParam;
1334 #else
1335 WORD code = (WORD)wParam;
1336 WORD pos = LOWORD(lParam);
1337 HWND control = (HWND)HIWORD(lParam);
1338 #endif
1339 MSWOnHScroll(code, pos, (WXHWND) control);
1340 break;
1341 }
1342 case WM_VSCROLL:
1343 {
1344 #ifdef __WIN32__
1345 WORD code = LOWORD(wParam);
1346 WORD pos = HIWORD(wParam);
1347 HWND control = (HWND)lParam;
1348 #else
1349 WORD code = (WORD)wParam;
1350 WORD pos = LOWORD(lParam);
1351 HWND control = (HWND)HIWORD(lParam);
1352 #endif
1353 MSWOnVScroll(code, pos, (WXHWND) control);
1354 break;
1355 }
1356 #ifdef __WIN32__
1357 case WM_CTLCOLORBTN:
1358 {
1359 int nCtlColor = CTLCOLOR_BTN;
1360 HWND control = (HWND)lParam;
1361 HDC pDC = (HDC)wParam;
1362 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1363 message, wParam, lParam);
1364 break;
1365 }
1366 case WM_CTLCOLORDLG:
1367 {
1368 int nCtlColor = CTLCOLOR_DLG;
1369 HWND control = (HWND)lParam;
1370 HDC pDC = (HDC)wParam;
1371 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1372 message, wParam, lParam);\
1373 break;
1374 }
1375 case WM_CTLCOLORLISTBOX:
1376 {
1377 int nCtlColor = CTLCOLOR_LISTBOX;
1378 HWND control = (HWND)lParam;
1379 HDC pDC = (HDC)wParam;
1380 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1381 message, wParam, lParam);
1382 break;
1383 }
1384 case WM_CTLCOLORMSGBOX:
1385 {
1386 int nCtlColor = CTLCOLOR_MSGBOX;
1387 HWND control = (HWND)lParam;
1388 HDC pDC = (HDC)wParam;
1389 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1390 message, wParam, lParam);
1391 break;
1392 }
1393 case WM_CTLCOLORSCROLLBAR:
1394 {
1395 int nCtlColor = CTLCOLOR_SCROLLBAR;
1396 HWND control = (HWND)lParam;
1397 HDC pDC = (HDC)wParam;
1398 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1399 message, wParam, lParam);
1400 break;
1401 }
1402 case WM_CTLCOLORSTATIC:
1403 {
1404 int nCtlColor = CTLCOLOR_STATIC;
1405 HWND control = (HWND)lParam;
1406 HDC pDC = (HDC)wParam;
1407 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1408 message, wParam, lParam);
1409 break;
1410 }
1411 case WM_CTLCOLOREDIT:
1412 {
1413 int nCtlColor = CTLCOLOR_EDIT;
1414 HWND control = (HWND)lParam;
1415 HDC pDC = (HDC)wParam;
1416 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1417 message, wParam, lParam);
1418 break;
1419 }
1420 #else
1421 case WM_CTLCOLOR:
1422 {
1423 HWND control = (HWND)LOWORD(lParam);
1424 int nCtlColor = (int)HIWORD(lParam);
1425 HDC pDC = (HDC)wParam;
1426 return (DWORD)MSWOnCtlColor((WXHDC) pDC, (WXHWND) control, nCtlColor,
1427 message, wParam, lParam);
1428 break;
1429 }
1430 #endif
1431 case WM_SYSCOLORCHANGE:
1432 {
1433 // Return value of 0 means, we processed it.
1434 if (MSWOnColorChange((WXHWND) hWnd, message, wParam, lParam) == 0)
1435 return 0;
1436 else
1437 return MSWDefWindowProc(message, wParam, lParam );
1438 break;
1439 }
1440 case WM_ERASEBKGND:
1441 {
1442 // Prevents flicker when dragging
1443 if (IsIconic(hWnd)) return 1;
1444
1445 // EXPERIMENTAL
1446 // return 1;
1447 if (!MSWOnEraseBkgnd((WXHDC) (HDC)wParam))
1448 return 0; // Default(); MSWDefWindowProc(message, wParam, lParam );
1449 else return 1;
1450 break;
1451 }
1452 case WM_MDIACTIVATE:
1453 {
1454 #ifdef __WIN32__
1455 HWND hWndActivate = GET_WM_MDIACTIVATE_HWNDACTIVATE(wParam,lParam);
1456 HWND hWndDeactivate = GET_WM_MDIACTIVATE_HWNDDEACT(wParam,lParam);
1457 BOOL activate = GET_WM_MDIACTIVATE_FACTIVATE(hWnd,wParam,lParam);
1458 return MSWOnMDIActivate((long) activate, (WXHWND) hWndActivate, (WXHWND) hWndDeactivate);
1459 #else
1460 return MSWOnMDIActivate((BOOL)wParam, (HWND)LOWORD(lParam),
1461 (HWND)HIWORD(lParam));
1462 #endif
1463 }
1464 case WM_DROPFILES:
1465 {
1466 MSWOnDropFiles(wParam);
1467 break;
1468 }
1469 case WM_INITDIALOG:
1470 {
1471 return 0; // MSWOnInitDialog((WXHWND)(HWND)wParam);
1472 break;
1473 }
1474 case WM_QUERYENDSESSION:
1475 {
1476 // Same as WM_CLOSE, but inverted results. Thx Microsoft :-)
1477 return MSWOnClose();
1478 break;
1479 }
1480 case WM_CLOSE:
1481 {
1482 if (MSWOnClose())
1483 return 0L;
1484 else
1485 return 1L;
1486 break;
1487 }
1488
1489 case WM_GETMINMAXINFO:
1490 {
1491 MINMAXINFO *info = (MINMAXINFO *)lParam;
1492 if (m_minSizeX != -1)
1493 info->ptMinTrackSize.x = (int)m_minSizeX;
1494 if (m_minSizeY != -1)
1495 info->ptMinTrackSize.y = (int)m_minSizeY;
1496 if (m_maxSizeX != -1)
1497 info->ptMaxTrackSize.x = (int)m_maxSizeX;
1498 if (m_maxSizeY != -1)
1499 info->ptMaxTrackSize.y = (int)m_maxSizeY;
1500 return MSWDefWindowProc(message, wParam, lParam );
1501 break;
1502 }
1503
1504 /*
1505 #if HAVE_SOCKET
1506 case WM_TIMER:
1507 {
1508 __ddeUnblock(hWnd, wParam);
1509 break;
1510 }
1511
1512 case ASYNC_SELECT_MESSAGE:
1513 return ddeWindowProc(hWnd,message,wParam,lParam);
1514 #endif
1515 */
1516
1517 default:
1518 return MSWDefWindowProc(message, wParam, lParam );
1519 }
1520 return 0; // Success: we processed this command.
1521 }
1522
1523 // Dialog window proc
1524 LONG APIENTRY _EXPORT
1525 wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1526 {
1527 return 0;
1528 }
1529
1530 wxList *wxWinHandleList = NULL;
1531 wxWindow *wxFindWinFromHandle(WXHWND hWnd)
1532 {
1533 wxNode *node = wxWinHandleList->Find((long)hWnd);
1534 if (!node)
1535 return NULL;
1536 return (wxWindow *)node->Data();
1537 }
1538
1539 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
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 log target if we've got one
1684 #if USE_DRAG_AND_DROP
1685 if ( m_pDropTarget != 0 ) {
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_RET( 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_RET( 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 //wxDebugMsg("LButtonDown\n") ;
2231 wxMouseEvent event(wxEVENT_TYPE_LEFT_DOWN);
2232
2233 /*
2234 float px = (float)x;
2235 float py = (float)y;
2236
2237 MSWDeviceToLogical(&px, &py);
2238
2239 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2240 */
2241
2242 event.m_x = x; event.m_y = y;
2243 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2244 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2245 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2246 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2247 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2248 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2249 event.m_eventObject = this;
2250
2251 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DOWN;
2252 GetEventHandler()->OldOnMouseEvent(event);
2253 }
2254
2255 void wxWindow::MSWOnLButtonUp(const int x, const int y, const WXUINT flags)
2256 {
2257 //wxDebugMsg("LButtonUp\n") ;
2258 wxMouseEvent event(wxEVENT_TYPE_LEFT_UP);
2259
2260 /*
2261 float px = (float)x;
2262 float py = (float)y;
2263
2264 MSWDeviceToLogical(&px, &py);
2265
2266 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2267 */
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_UP;
2279
2280 GetEventHandler()->OldOnMouseEvent(event);
2281 }
2282
2283 void wxWindow::MSWOnLButtonDClick(const int x, const int y, const WXUINT flags)
2284 {
2285 //wxDebugMsg("LButtonDClick\n") ;
2286 /* MATTHEW: If dclick not allowed, generate another single-click */
2287 wxMouseEvent event(m_doubleClickAllowed ?
2288 wxEVENT_TYPE_LEFT_DCLICK : wxEVENT_TYPE_LEFT_DOWN);
2289
2290 /*
2291 float px = (float)x;
2292 float py = (float)y;
2293
2294 MSWDeviceToLogical(&px, &py);
2295
2296 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2297 */
2298
2299 event.m_x = x; event.m_y = y;
2300 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2301 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2302 event.m_leftDown = ((flags & MK_LBUTTON != 0));
2303 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2304 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2305 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2306 event.m_eventObject = this;
2307
2308 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DCLICK;
2309
2310 // if (m_doubleClickAllowed)
2311 GetEventHandler()->OldOnMouseEvent(event);
2312 }
2313
2314 void wxWindow::MSWOnMButtonDown(const int x, const int y, const WXUINT flags)
2315 {
2316 #if 0 // defined(__WIN32__) && !defined(__WIN95__)
2317 // DClick not clean supported on Win3.1, except if someone know
2318 // how to emulate Sleep()...
2319 // This means that your app will receive Down-Up-Dclick sequences
2320 // rather than Dclick
2321 if (m_doubleClickAllowed)
2322 {
2323 UINT time = GetDoubleClickTime() ;
2324 Sleep(time) ;
2325 MSG dummy ;
2326 if (PeekMessage(&dummy,m_hWnd,
2327 WM_MBUTTONDBLCLK,WM_MBUTTONDBLCLK,
2328 PM_NOREMOVE)
2329 )
2330 {
2331 PeekMessage(&dummy,m_hWnd,WM_MBUTTONUP,WM_MBUTTONUP,PM_REMOVE);
2332 return;
2333 }
2334 }
2335 #endif
2336
2337 //wxDebugMsg("MButtonDown\n") ;
2338 wxMouseEvent event(wxEVENT_TYPE_MIDDLE_DOWN);
2339
2340 /*
2341 float px = (float)x;
2342 float py = (float)y;
2343
2344 MSWDeviceToLogical(&px, &py);
2345
2346 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2347 */
2348
2349 event.m_x = x; event.m_y = y;
2350 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2351 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2352 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2353 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2354 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2355 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2356 event.m_eventObject = this;
2357
2358 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DOWN;
2359 GetEventHandler()->OldOnMouseEvent(event);
2360 }
2361
2362 void wxWindow::MSWOnMButtonUp(const int x, const int y, const WXUINT flags)
2363 {
2364 //wxDebugMsg("MButtonUp\n") ;
2365 wxMouseEvent event(wxEVENT_TYPE_MIDDLE_UP);
2366
2367 /*
2368 float px = (float)x;
2369 float py = (float)y;
2370
2371 MSWDeviceToLogical(&px, &py);
2372
2373 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2374 */
2375
2376 event.m_x = x; event.m_y = y;
2377 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2378 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2379 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2380 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2381 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2382 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2383 event.m_eventObject = this;
2384
2385 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_UP;
2386 GetEventHandler()->OldOnMouseEvent(event);
2387 }
2388
2389 void wxWindow::MSWOnMButtonDClick(const int x, const int y, const WXUINT flags)
2390 {
2391 //wxDebugMsg("MButtonDClick\n") ;
2392 /* MATTHEW: If dclick not allowed, generate another single-click */
2393 wxMouseEvent event((m_doubleClickAllowed) ?
2394 wxEVENT_TYPE_MIDDLE_DCLICK : wxEVENT_TYPE_MIDDLE_DOWN);
2395
2396 /*
2397 float px = (float)x;
2398 float py = (float)y;
2399
2400 MSWDeviceToLogical(&px, &py);
2401
2402 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2403 */
2404
2405 event.m_x = x; event.m_y = y;
2406 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2407 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2408 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2409 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2410 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2411 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2412 event.m_eventObject = this;
2413
2414 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DCLICK;
2415 // if (m_doubleClickAllowed)
2416 GetEventHandler()->OldOnMouseEvent(event);
2417 }
2418
2419 void wxWindow::MSWOnRButtonDown(const int x, const int y, const WXUINT flags)
2420 {
2421 #if 0 // defined(__WIN32__) && !defined(__WIN95__)
2422 // DClick not clean supported on Win3.1, except if someone know
2423 // how to emulate Sleep()...
2424 // This means that your app will receive Down-Up-Dclick sequences
2425 // rather than Dclick
2426 if (m_doubleClickAllowed)
2427 {
2428 UINT time = GetDoubleClickTime() ;
2429 Sleep(time) ;
2430 MSG dummy ;
2431 if (PeekMessage(&dummy,m_hWnd,
2432 WM_RBUTTONDBLCLK,WM_RBUTTONDBLCLK,
2433 PM_NOREMOVE)
2434 )
2435 {
2436 PeekMessage(&dummy,m_hWnd,WM_RBUTTONUP,WM_RBUTTONUP,PM_REMOVE);
2437 return;
2438 }
2439 }
2440 #endif
2441
2442 //wxDebugMsg("RButtonDown\n") ;
2443 wxMouseEvent event(wxEVENT_TYPE_RIGHT_DOWN);
2444
2445 /*
2446 float px = (float)x;
2447 float py = (float)y;
2448
2449 MSWDeviceToLogical(&px, &py);
2450
2451 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2452 */
2453
2454 event.m_x = x; event.m_y = y;
2455 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2456 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2457 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2458 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2459 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2460 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2461 event.m_eventObject = this;
2462
2463 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_RIGHT_DOWN;
2464 GetEventHandler()->OldOnMouseEvent(event);
2465 }
2466
2467 void wxWindow::MSWOnRButtonUp(const int x, const int y, const WXUINT flags)
2468 {
2469 //wxDebugMsg("RButtonUp\n") ;
2470 wxMouseEvent event(wxEVENT_TYPE_RIGHT_UP);
2471
2472 /*
2473 float px = (float)x;
2474 float py = (float)y;
2475
2476 MSWDeviceToLogical(&px, &py);
2477
2478 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2479 */
2480
2481 event.m_x = x; event.m_y = y;
2482 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2483 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2484 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2485 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2486 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2487 event.m_eventObject = this;
2488 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2489
2490 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_RIGHT_UP;
2491 GetEventHandler()->OldOnMouseEvent(event);
2492 }
2493
2494 void wxWindow::MSWOnRButtonDClick(const int x, const int y, const WXUINT flags)
2495 {
2496 //wxDebugMsg("RButtonDClick\n") ;
2497 /* MATTHEW: If dclick not allowed, generate another single-click */
2498 wxMouseEvent event((m_doubleClickAllowed) ?
2499 wxEVENT_TYPE_RIGHT_DCLICK : wxEVENT_TYPE_RIGHT_DOWN);
2500
2501 /*
2502 float px = (float)x;
2503 float py = (float)y;
2504
2505 MSWDeviceToLogical(&px, &py);
2506
2507 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2508 */
2509
2510 event.m_x = x; event.m_y = y;
2511 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2512 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2513 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2514 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2515 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2516 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2517 event.m_eventObject = this;
2518
2519 m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_RIGHT_DCLICK;
2520 // if (m_doubleClickAllowed)
2521 GetEventHandler()->OldOnMouseEvent(event);
2522 }
2523
2524 void wxWindow::MSWOnMouseMove(const int x, const int y, const WXUINT flags)
2525 {
2526 // 'normal' move event...
2527 // Set cursor, but only if we're not in 'busy' mode
2528
2529 // Trouble with this is that it sets the cursor for controls too :-(
2530 if (m_windowCursor.Ok() && !wxIsBusy())
2531 ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
2532
2533 wxMouseEvent event(wxEVENT_TYPE_MOTION);
2534
2535 /*
2536 float px = (float)x;
2537 float py = (float)y;
2538
2539 MSWDeviceToLogical(&px, &py);
2540
2541 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2542 */
2543
2544 event.m_x = x; event.m_y = y;
2545 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2546 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2547 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2548 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2549 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2550 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2551 event.m_eventObject = this;
2552
2553 // Window gets a click down message followed by a mouse move
2554 // message even if position isn't changed! We want to discard
2555 // the trailing move event if x and y are the same.
2556 if ((m_lastEvent == wxEVENT_TYPE_RIGHT_DOWN || m_lastEvent == wxEVENT_TYPE_LEFT_DOWN ||
2557 m_lastEvent == wxEVENT_TYPE_MIDDLE_DOWN) &&
2558 (m_lastXPos == event.m_x && m_lastYPos == event.m_y))
2559 {
2560 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2561 m_lastEvent = wxEVENT_TYPE_MOTION;
2562 return;
2563 }
2564
2565 m_lastEvent = wxEVENT_TYPE_MOTION;
2566 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2567 GetEventHandler()->OldOnMouseEvent(event);
2568 }
2569
2570 /* TODO put back leave/enter code if required
2571 */
2572 #if 0
2573 void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
2574 {
2575 //wxDebugMsg("Client 0x%08x Move Msg %d,%d\n",this,x,y) ;
2576
2577 // #if MOUSE_EXIT_FIX //Should work now!!
2578
2579 // Don't do the Leave/Enter fix if we've captured the window,
2580 // or SetCapture won't work properly.
2581 if (!m_winCaptured)
2582 {
2583 HWND hunder ;
2584 POINT pt ;
2585 // See if we Leave/Enter the window.
2586 GetCursorPos(&pt) ;
2587 hunder = WindowFromPoint(pt) ;
2588 if (hunder==m_hWnd)
2589 {
2590 // I'm in the Window, but perhaps in NC area.
2591 RECT wind ;
2592 RECT nc ;
2593 GetClientRect(m_hWnd,&wind) ;
2594 GetWindowRect(m_hWnd,&nc) ;
2595 pt.x -= nc.left ;
2596 pt.y -= nc.top ;
2597 wind.left += WINDOW_MARGIN ; // to be able to 'see' leave
2598 wind.top += WINDOW_MARGIN ; // to be able to 'see' leave
2599 wind.right -= WINDOW_MARGIN ; // to be able to 'see' leave
2600 wind.bottom -= WINDOW_MARGIN ; // to be able to 'see' leave
2601
2602 if (!PtInRect(&wind,pt))
2603 hunder = NULL ; // So, I can simulate a Leave event...
2604 }
2605
2606 if (hunder!=m_hWnd)
2607 {
2608 if (m_mouseInWindow)
2609 {
2610 m_mouseInWindow = FALSE ;
2611 // Capture/Release is no more needed...
2612 //ReleaseCapture() ;
2613 MSWOnMouseLeave(x,y,flags) ;
2614 return ;
2615 }
2616 // We never want to see Enter or Motion in this part of the Window...
2617 return ;
2618 }
2619 else
2620 {
2621 // Event was triggered while I'm really into my client area.
2622 // Do an Enter if not done.
2623 if (!m_mouseInWindow)
2624 {
2625 m_mouseInWindow = TRUE ;
2626 // Capture/Release is no more needed...
2627 //SetCapture(m_hWnd) ;
2628 // Set cursor, but only if we're not in 'busy' mode
2629 if (m_windowCursor.Ok() && !wxIsBusy())
2630 ::SetCursor(m_windowCursor.ms_cursor);
2631 MSWOnMouseEnter(x,y,flags) ;
2632 return ;
2633 }
2634 }
2635 }
2636 // #endif //MOUSE_EXIT_FIX
2637
2638 // 'normal' move event...
2639 // Set cursor, but only if we're not in 'busy' mode
2640 if (m_windowCursor.Ok() && !wxIsBusy())
2641 ::SetCursor(m_windowCursor.ms_cursor);
2642
2643 wxMouseEvent event(wxEVENT_TYPE_MOTION);
2644
2645 /*
2646 float px = (float)x;
2647 float py = (float)y;
2648
2649 MSWDeviceToLogical(&px, &py);
2650
2651 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2652 */
2653
2654 event.m_x = x; event.m_y = y;
2655 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2656 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2657 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2658 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2659 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2660 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2661 event.m_eventObject = this;
2662
2663 // Window gets a click down message followed by a mouse move
2664 // message even if position isn't changed! We want to discard
2665 // the trailing move event if x and y are the same.
2666 if ((m_lastEvent == wxEVENT_TYPE_RIGHT_DOWN || m_lastEvent == wxEVENT_TYPE_LEFT_DOWN ||
2667 m_lastEvent == wxEVENT_TYPE_MIDDLE_DOWN) &&
2668 (m_lastXPos == event.m_x && m_lastYPos == event.m_y))
2669 {
2670 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2671 m_lastEvent = wxEVENT_TYPE_MOTION;
2672 return;
2673 }
2674
2675 m_lastEvent = wxEVENT_TYPE_MOTION;
2676 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2677 GetEventHandler()->OldOnMouseEvent(event);
2678 }
2679 #endif
2680
2681 void wxWindow::MSWOnMouseEnter(const int x, const int y, const WXUINT flags)
2682 {
2683 //wxDebugMsg("Client 0x%08x Enter %d,%d\n",this,x,y) ;
2684
2685 // Set cursor, but only if we're not in 'busy' mode
2686 if (m_windowCursor.Ok() && !wxIsBusy())
2687 ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
2688
2689 wxMouseEvent event(wxEVENT_TYPE_ENTER_WINDOW);
2690
2691 /*
2692 float px = (float)x;
2693 float py = (float)y;
2694
2695 MSWDeviceToLogical(&px, &py);
2696
2697 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2698 */
2699
2700 event.m_x = x; event.m_y = y;
2701 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2702 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2703 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2704 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2705 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2706 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2707 event.m_eventObject = this;
2708
2709 m_lastEvent = wxEVENT_TYPE_ENTER_WINDOW;
2710 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2711 GetEventHandler()->OldOnMouseEvent(event);
2712 }
2713
2714 void wxWindow::MSWOnMouseLeave(const int x, const int y, const WXUINT flags)
2715 {
2716 //wxDebugMsg("Client 0x%08x Leave %d,%d\n",this,x,y) ;
2717
2718 // Set cursor, but only if we're not in 'busy' mode
2719 if (m_windowCursor.Ok() && !wxIsBusy())
2720 ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
2721
2722 wxMouseEvent event(wxEVENT_TYPE_LEAVE_WINDOW);
2723
2724 /*
2725 float px = (float)x;
2726 float py = (float)y;
2727
2728 MSWDeviceToLogical(&px, &py);
2729
2730 CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
2731 */
2732
2733 event.m_x = x; event.m_y = y;
2734 event.m_shiftDown = ((flags & MK_SHIFT) != 0);
2735 event.m_controlDown = ((flags & MK_CONTROL) != 0);
2736 event.m_leftDown = ((flags & MK_LBUTTON) != 0);
2737 event.m_middleDown = ((flags & MK_MBUTTON) != 0);
2738 event.m_rightDown = ((flags & MK_RBUTTON) != 0);
2739 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2740 event.m_eventObject = this;
2741
2742 m_lastEvent = wxEVENT_TYPE_LEAVE_WINDOW;
2743 m_lastXPos = event.m_x; m_lastYPos = event.m_y;
2744 GetEventHandler()->OldOnMouseEvent(event);
2745 }
2746
2747 void wxWindow::MSWOnChar(const WXWORD wParam, const WXLPARAM lParam, const bool isASCII)
2748 {
2749 int id;
2750 bool tempControlDown = FALSE;
2751 if (isASCII)
2752 {
2753 // If 1 -> 26, translate to CTRL plus a letter.
2754 id = wParam;
2755 if ((id > 0) && (id < 27))
2756 {
2757 switch (id)
2758 {
2759 case 13:
2760 {
2761 id = WXK_RETURN;
2762 break;
2763 }
2764 case 8:
2765 {
2766 id = WXK_BACK;
2767 break;
2768 }
2769 case 9:
2770 {
2771 id = WXK_TAB;
2772 break;
2773 }
2774 default:
2775 {
2776 tempControlDown = TRUE;
2777 id = id + 96;
2778 }
2779 }
2780 }
2781 }
2782 else
2783 if ((id = wxCharCodeMSWToWX(wParam)) == 0)
2784 id = -1;
2785
2786 if (id > -1)
2787 {
2788 wxKeyEvent event(wxEVT_CHAR);
2789 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
2790 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
2791 if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
2792 event.m_altDown = TRUE;
2793
2794 event.m_eventObject = this;
2795 event.m_keyCode = id;
2796 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
2797
2798 POINT pt ;
2799 GetCursorPos(&pt) ;
2800 RECT rect ;
2801 GetWindowRect((HWND) GetHWND(),&rect) ;
2802 pt.x -= rect.left ;
2803 pt.y -= rect.top ;
2804
2805 /*
2806 float fx,fy ;
2807 fx = (float)pt.x ;
2808 fy = (float)pt.y ;
2809 MSWDeviceToLogical(&fx,&fy) ;
2810 CalcUnscrolledPosition((int)fx,(int)fy,&event.m_x,&event.m_y) ;
2811 */
2812 event.m_x = pt.x; event.m_y = pt.y;
2813
2814 #if WXWIN_COMPATIBILITY
2815 GetEventHandler()->OldOnChar(event);
2816 #else
2817 if (!GetEventHandler()->ProcessEvent(event))
2818 Default();
2819 #endif
2820 }
2821 }
2822
2823 void wxWindow::MSWOnJoyDown(const int joystick, const int x, const int y, const WXUINT flags)
2824 {
2825 int buttons = 0;
2826 int change = 0;
2827 if (flags & JOY_BUTTON1CHG)
2828 change = wxJOY_BUTTON1;
2829 if (flags & JOY_BUTTON2CHG)
2830 change = wxJOY_BUTTON2;
2831 if (flags & JOY_BUTTON3CHG)
2832 change = wxJOY_BUTTON3;
2833 if (flags & JOY_BUTTON4CHG)
2834 change = wxJOY_BUTTON4;
2835
2836 if (flags & JOY_BUTTON1)
2837 buttons |= wxJOY_BUTTON1;
2838 if (flags & JOY_BUTTON2)
2839 buttons |= wxJOY_BUTTON2;
2840 if (flags & JOY_BUTTON3)
2841 buttons |= wxJOY_BUTTON3;
2842 if (flags & JOY_BUTTON4)
2843 buttons |= wxJOY_BUTTON4;
2844
2845 wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN, buttons, joystick, change);
2846 event.SetPosition(wxPoint(x, y));
2847 event.SetEventObject(this);
2848
2849 GetEventHandler()->ProcessEvent(event);
2850 }
2851
2852 void wxWindow::MSWOnJoyUp(const int joystick, const int x, const int y, const WXUINT flags)
2853 {
2854 int buttons = 0;
2855 int change = 0;
2856 if (flags & JOY_BUTTON1CHG)
2857 change = wxJOY_BUTTON1;
2858 if (flags & JOY_BUTTON2CHG)
2859 change = wxJOY_BUTTON2;
2860 if (flags & JOY_BUTTON3CHG)
2861 change = wxJOY_BUTTON3;
2862 if (flags & JOY_BUTTON4CHG)
2863 change = wxJOY_BUTTON4;
2864
2865 if (flags & JOY_BUTTON1)
2866 buttons |= wxJOY_BUTTON1;
2867 if (flags & JOY_BUTTON2)
2868 buttons |= wxJOY_BUTTON2;
2869 if (flags & JOY_BUTTON3)
2870 buttons |= wxJOY_BUTTON3;
2871 if (flags & JOY_BUTTON4)
2872 buttons |= wxJOY_BUTTON4;
2873
2874 wxJoystickEvent event(wxEVT_JOY_BUTTON_UP, buttons, joystick, change);
2875 event.SetPosition(wxPoint(x, y));
2876 event.SetEventObject(this);
2877
2878 GetEventHandler()->ProcessEvent(event);
2879 }
2880
2881 void wxWindow::MSWOnJoyMove(const int joystick, const int x, const int y, const WXUINT flags)
2882 {
2883 int buttons = 0;
2884 if (flags & JOY_BUTTON1)
2885 buttons |= wxJOY_BUTTON1;
2886 if (flags & JOY_BUTTON2)
2887 buttons |= wxJOY_BUTTON2;
2888 if (flags & JOY_BUTTON3)
2889 buttons |= wxJOY_BUTTON3;
2890 if (flags & JOY_BUTTON4)
2891 buttons |= wxJOY_BUTTON4;
2892
2893 wxJoystickEvent event(wxEVT_JOY_MOVE, buttons, joystick, 0);
2894 event.SetPosition(wxPoint(x, y));
2895 event.SetEventObject(this);
2896
2897 GetEventHandler()->ProcessEvent(event);
2898 }
2899
2900 void wxWindow::MSWOnJoyZMove(const int joystick, const int z, const WXUINT flags)
2901 {
2902 int buttons = 0;
2903 if (flags & JOY_BUTTON1)
2904 buttons |= wxJOY_BUTTON1;
2905 if (flags & JOY_BUTTON2)
2906 buttons |= wxJOY_BUTTON2;
2907 if (flags & JOY_BUTTON3)
2908 buttons |= wxJOY_BUTTON3;
2909 if (flags & JOY_BUTTON4)
2910 buttons |= wxJOY_BUTTON4;
2911
2912 wxJoystickEvent event(wxEVT_JOY_ZMOVE, buttons, joystick, 0);
2913 event.SetZPosition(z);
2914 event.SetEventObject(this);
2915
2916 GetEventHandler()->ProcessEvent(event);
2917 }
2918
2919 void wxWindow::MSWOnVScroll(const WXWORD wParam, const WXWORD pos, const WXHWND control)
2920 {
2921 if (control)
2922 {
2923 wxWindow *child = wxFindWinFromHandle(control);
2924 if ( child )
2925 child->MSWOnVScroll(wParam, pos, control);
2926 return;
2927 }
2928
2929 wxScrollEvent event;
2930 event.SetPosition(pos);
2931 event.SetOrientation(wxVERTICAL);
2932 event.m_eventObject = this;
2933
2934 switch ( wParam )
2935 {
2936 case SB_TOP:
2937 event.m_eventType = wxEVENT_TYPE_SCROLL_TOP;
2938 break;
2939
2940 case SB_BOTTOM:
2941 event.m_eventType = wxEVENT_TYPE_SCROLL_BOTTOM;
2942 break;
2943
2944 case SB_LINEUP:
2945 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEUP;
2946 break;
2947
2948 case SB_LINEDOWN:
2949 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEDOWN;
2950 break;
2951
2952 case SB_PAGEUP:
2953 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEUP;
2954 break;
2955
2956 case SB_PAGEDOWN:
2957 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEDOWN;
2958 break;
2959
2960 case SB_THUMBTRACK:
2961 case SB_THUMBPOSITION:
2962 event.m_eventType = wxEVENT_TYPE_SCROLL_THUMBTRACK;
2963 break;
2964
2965 default:
2966 return;
2967 break;
2968 }
2969
2970 if (!GetEventHandler()->ProcessEvent(event))
2971 #if WXWIN_COMPATIBILITY
2972 GetEventHandler()->OldOnScroll(event);
2973 #else
2974 Default();
2975 #endif
2976 }
2977
2978 void wxWindow::MSWOnHScroll( const WXWORD wParam, const WXWORD pos, const WXHWND control)
2979 {
2980 if (control)
2981 {
2982 wxWindow *child = wxFindWinFromHandle(control);
2983 if ( child )
2984 child->MSWOnHScroll(wParam, pos, control);
2985 return;
2986 }
2987
2988 wxScrollEvent event;
2989 event.SetPosition(pos);
2990 event.SetOrientation(wxHORIZONTAL);
2991 event.m_eventObject = this;
2992
2993 switch ( wParam )
2994 {
2995 case SB_TOP:
2996 event.m_eventType = wxEVENT_TYPE_SCROLL_TOP;
2997 break;
2998
2999 case SB_BOTTOM:
3000 event.m_eventType = wxEVENT_TYPE_SCROLL_BOTTOM;
3001 break;
3002
3003 case SB_LINEUP:
3004 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEUP;
3005 break;
3006
3007 case SB_LINEDOWN:
3008 event.m_eventType = wxEVENT_TYPE_SCROLL_LINEDOWN;
3009 break;
3010
3011 case SB_PAGEUP:
3012 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEUP;
3013 break;
3014
3015 case SB_PAGEDOWN:
3016 event.m_eventType = wxEVENT_TYPE_SCROLL_PAGEDOWN;
3017 break;
3018
3019 case SB_THUMBTRACK:
3020 case SB_THUMBPOSITION:
3021 event.m_eventType = wxEVENT_TYPE_SCROLL_THUMBTRACK;
3022 break;
3023
3024 default:
3025 return;
3026 break;
3027 }
3028 if (!GetEventHandler()->ProcessEvent(event))
3029 #if WXWIN_COMPATIBILITY
3030 GetEventHandler()->OldOnScroll(event);
3031 #else
3032 Default();
3033 #endif
3034 }
3035
3036 void wxWindow::MSWOnShow(bool show, int status)
3037 {
3038 wxShowEvent event(GetId(), show);
3039 event.m_eventObject = this;
3040 GetEventHandler()->ProcessEvent(event);
3041 }
3042
3043 bool wxWindow::MSWOnInitDialog(WXHWND WXUNUSED(hWndFocus))
3044 {
3045 wxInitDialogEvent event(GetId());
3046 event.m_eventObject = this;
3047 GetEventHandler()->ProcessEvent(event);
3048 return TRUE;
3049 }
3050
3051 void wxWindow::InitDialog(void)
3052 {
3053 wxInitDialogEvent event(GetId());
3054 event.SetEventObject( this );
3055 GetEventHandler()->ProcessEvent(event);
3056 }
3057
3058 // Default init dialog behaviour is to transfer data to window
3059 void wxWindow::OnInitDialog(wxInitDialogEvent& event)
3060 {
3061 TransferDataToWindow();
3062 }
3063
3064 void wxGetCharSize(WXHWND wnd, int *x, int *y,wxFont *the_font)
3065 {
3066 TEXTMETRIC tm;
3067 HDC dc = ::GetDC((HWND) wnd);
3068 HFONT fnt =0;
3069 HFONT was = 0;
3070 if (the_font)
3071 {
3072 #if DEBUG > 1
3073 wxDebugMsg("wxGetCharSize: Selecting HFONT %X\n", fnt);
3074 #endif
3075 // the_font->UseResource();
3076 // the_font->RealizeResource();
3077 if ((fnt=(HFONT) the_font->GetResourceHandle()))
3078 was = SelectObject(dc,fnt) ;
3079 }
3080 GetTextMetrics(dc, &tm);
3081 if (the_font && fnt && was)
3082 {
3083 #if DEBUG > 1
3084 wxDebugMsg("wxGetCharSize: Selecting old HFONT %X\n", was);
3085 #endif
3086 SelectObject(dc,was) ;
3087 }
3088 ReleaseDC((HWND)wnd, dc);
3089 *x = tm.tmAveCharWidth;
3090 *y = tm.tmHeight + tm.tmExternalLeading;
3091
3092 // if (the_font)
3093 // the_font->ReleaseResource();
3094 }
3095
3096 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
3097 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
3098 int wxCharCodeMSWToWX(int keySym)
3099 {
3100 int id = 0;
3101 switch (keySym)
3102 {
3103 case VK_CANCEL: id = WXK_CANCEL; break;
3104 case VK_BACK: id = WXK_BACK; break;
3105 case VK_TAB: id = WXK_TAB; break;
3106 case VK_CLEAR: id = WXK_CLEAR; break;
3107 case VK_RETURN: id = WXK_RETURN; break;
3108 case VK_SHIFT: id = WXK_SHIFT; break;
3109 case VK_CONTROL: id = WXK_CONTROL; break;
3110 case VK_MENU : id = WXK_MENU; break;
3111 case VK_PAUSE: id = WXK_PAUSE; break;
3112 case VK_SPACE: id = WXK_SPACE; break;
3113 case VK_ESCAPE: id = WXK_ESCAPE; break;
3114 case VK_PRIOR: id = WXK_PRIOR; break;
3115 case VK_NEXT : id = WXK_NEXT; break;
3116 case VK_END: id = WXK_END; break;
3117 case VK_HOME : id = WXK_HOME; break;
3118 case VK_LEFT : id = WXK_LEFT; break;
3119 case VK_UP: id = WXK_UP; break;
3120 case VK_RIGHT: id = WXK_RIGHT; break;
3121 case VK_DOWN : id = WXK_DOWN; break;
3122 case VK_SELECT: id = WXK_SELECT; break;
3123 case VK_PRINT: id = WXK_PRINT; break;
3124 case VK_EXECUTE: id = WXK_EXECUTE; break;
3125 case VK_INSERT: id = WXK_INSERT; break;
3126 case VK_DELETE: id = WXK_DELETE; break;
3127 case VK_HELP : id = WXK_HELP; break;
3128 case VK_NUMPAD0: id = WXK_NUMPAD0; break;
3129 case VK_NUMPAD1: id = WXK_NUMPAD1; break;
3130 case VK_NUMPAD2: id = WXK_NUMPAD2; break;
3131 case VK_NUMPAD3: id = WXK_NUMPAD3; break;
3132 case VK_NUMPAD4: id = WXK_NUMPAD4; break;
3133 case VK_NUMPAD5: id = WXK_NUMPAD5; break;
3134 case VK_NUMPAD6: id = WXK_NUMPAD6; break;
3135 case VK_NUMPAD7: id = WXK_NUMPAD7; break;
3136 case VK_NUMPAD8: id = WXK_NUMPAD8; break;
3137 case VK_NUMPAD9: id = WXK_NUMPAD9; break;
3138 case VK_MULTIPLY: id = WXK_MULTIPLY; break;
3139 case VK_ADD: id = WXK_ADD; break;
3140 case VK_SUBTRACT: id = WXK_SUBTRACT; break;
3141 case VK_DECIMAL: id = WXK_DECIMAL; break;
3142 case VK_DIVIDE: id = WXK_DIVIDE; break;
3143 case VK_F1: id = WXK_F1; break;
3144 case VK_F2: id = WXK_F2; break;
3145 case VK_F3: id = WXK_F3; break;
3146 case VK_F4: id = WXK_F4; break;
3147 case VK_F5: id = WXK_F5; break;
3148 case VK_F6: id = WXK_F6; break;
3149 case VK_F7: id = WXK_F7; break;
3150 case VK_F8: id = WXK_F8; break;
3151 case VK_F9: id = WXK_F9; break;
3152 case VK_F10: id = WXK_F10; break;
3153 case VK_F11: id = WXK_F11; break;
3154 case VK_F12: id = WXK_F12; break;
3155 case VK_F13: id = WXK_F13; break;
3156 case VK_F14: id = WXK_F14; break;
3157 case VK_F15: id = WXK_F15; break;
3158 case VK_F16: id = WXK_F16; break;
3159 case VK_F17: id = WXK_F17; break;
3160 case VK_F18: id = WXK_F18; break;
3161 case VK_F19: id = WXK_F19; break;
3162 case VK_F20: id = WXK_F20; break;
3163 case VK_F21: id = WXK_F21; break;
3164 case VK_F22: id = WXK_F22; break;
3165 case VK_F23: id = WXK_F23; break;
3166 case VK_F24: id = WXK_F24; break;
3167 case VK_NUMLOCK: id = WXK_NUMLOCK; break;
3168 case VK_SCROLL: id = WXK_SCROLL; break;
3169 default:
3170 {
3171 return 0;
3172 }
3173 }
3174 return id;
3175 }
3176
3177 int wxCharCodeWXToMSW(int id, bool *isVirtual)
3178 {
3179 *isVirtual = TRUE;
3180 int keySym = 0;
3181 switch (id)
3182 {
3183 case WXK_CANCEL: keySym = VK_CANCEL; break;
3184 case WXK_CLEAR: keySym = VK_CLEAR; break;
3185 case WXK_SHIFT: keySym = VK_SHIFT; break;
3186 case WXK_CONTROL: keySym = VK_CONTROL; break;
3187 case WXK_MENU : keySym = VK_MENU; break;
3188 case WXK_PAUSE: keySym = VK_PAUSE; break;
3189 case WXK_PRIOR: keySym = VK_PRIOR; break;
3190 case WXK_NEXT : keySym = VK_NEXT; break;
3191 case WXK_END: keySym = VK_END; break;
3192 case WXK_HOME : keySym = VK_HOME; break;
3193 case WXK_LEFT : keySym = VK_LEFT; break;
3194 case WXK_UP: keySym = VK_UP; break;
3195 case WXK_RIGHT: keySym = VK_RIGHT; break;
3196 case WXK_DOWN : keySym = VK_DOWN; break;
3197 case WXK_SELECT: keySym = VK_SELECT; break;
3198 case WXK_PRINT: keySym = VK_PRINT; break;
3199 case WXK_EXECUTE: keySym = VK_EXECUTE; break;
3200 case WXK_INSERT: keySym = VK_INSERT; break;
3201 case WXK_DELETE: keySym = VK_DELETE; break;
3202 case WXK_HELP : keySym = VK_HELP; break;
3203 case WXK_NUMPAD0: keySym = VK_NUMPAD0; break;
3204 case WXK_NUMPAD1: keySym = VK_NUMPAD1; break;
3205 case WXK_NUMPAD2: keySym = VK_NUMPAD2; break;
3206 case WXK_NUMPAD3: keySym = VK_NUMPAD3; break;
3207 case WXK_NUMPAD4: keySym = VK_NUMPAD4; break;
3208 case WXK_NUMPAD5: keySym = VK_NUMPAD5; break;
3209 case WXK_NUMPAD6: keySym = VK_NUMPAD6; break;
3210 case WXK_NUMPAD7: keySym = VK_NUMPAD7; break;
3211 case WXK_NUMPAD8: keySym = VK_NUMPAD8; break;
3212 case WXK_NUMPAD9: keySym = VK_NUMPAD9; break;
3213 case WXK_MULTIPLY: keySym = VK_MULTIPLY; break;
3214 case WXK_ADD: keySym = VK_ADD; break;
3215 case WXK_SUBTRACT: keySym = VK_SUBTRACT; break;
3216 case WXK_DECIMAL: keySym = VK_DECIMAL; break;
3217 case WXK_DIVIDE: keySym = VK_DIVIDE; break;
3218 case WXK_F1: keySym = VK_F1; break;
3219 case WXK_F2: keySym = VK_F2; break;
3220 case WXK_F3: keySym = VK_F3; break;
3221 case WXK_F4: keySym = VK_F4; break;
3222 case WXK_F5: keySym = VK_F5; break;
3223 case WXK_F6: keySym = VK_F6; break;
3224 case WXK_F7: keySym = VK_F7; break;
3225 case WXK_F8: keySym = VK_F8; break;
3226 case WXK_F9: keySym = VK_F9; break;
3227 case WXK_F10: keySym = VK_F10; break;
3228 case WXK_F11: keySym = VK_F11; break;
3229 case WXK_F12: keySym = VK_F12; break;
3230 case WXK_F13: keySym = VK_F13; break;
3231 case WXK_F14: keySym = VK_F14; break;
3232 case WXK_F15: keySym = VK_F15; break;
3233 case WXK_F16: keySym = VK_F16; break;
3234 case WXK_F17: keySym = VK_F17; break;
3235 case WXK_F18: keySym = VK_F18; break;
3236 case WXK_F19: keySym = VK_F19; break;
3237 case WXK_F20: keySym = VK_F20; break;
3238 case WXK_F21: keySym = VK_F21; break;
3239 case WXK_F22: keySym = VK_F22; break;
3240 case WXK_F23: keySym = VK_F23; break;
3241 case WXK_F24: keySym = VK_F24; break;
3242 case WXK_NUMLOCK: keySym = VK_NUMLOCK; break;
3243 case WXK_SCROLL: keySym = VK_SCROLL; break;
3244 default:
3245 {
3246 *isVirtual = FALSE;
3247 keySym = id;
3248 break;
3249 }
3250 }
3251 return keySym;
3252 }
3253
3254 // Caret manipulation
3255 void wxWindow::CreateCaret(const int w, const int h)
3256 {
3257 m_caretWidth = w;
3258 m_caretHeight = h;
3259 m_caretEnabled = TRUE;
3260 }
3261
3262 void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
3263 {
3264 // Not implemented
3265 }
3266
3267 void wxWindow::ShowCaret(const bool show)
3268 {
3269 if (m_caretEnabled)
3270 {
3271 if (show)
3272 ::ShowCaret((HWND) GetHWND());
3273 else
3274 ::HideCaret((HWND) GetHWND());
3275 m_caretShown = show;
3276 }
3277 }
3278
3279 void wxWindow::DestroyCaret(void)
3280 {
3281 m_caretEnabled = FALSE;
3282 }
3283
3284 void wxWindow::SetCaretPos(const int x, const int y)
3285 {
3286 ::SetCaretPos(x, y);
3287 }
3288
3289 void wxWindow::GetCaretPos(int *x, int *y) const
3290 {
3291 POINT point;
3292 ::GetCaretPos(&point);
3293 *x = point.x;
3294 *y = point.y;
3295 }
3296
3297 /*
3298 * Update iterator. Use from within OnPaint.
3299 */
3300
3301 static RECT gs_UpdateRect;
3302
3303 wxUpdateIterator::wxUpdateIterator(wxWindow* wnd)
3304 {
3305 current = 0; //start somewhere...
3306 #if defined(__WIN32__) && !defined(__win32s__)
3307 rlist = NULL; //make sure I don't free randomly
3308 int len = GetRegionData((HRGN) wnd->m_updateRgn,0,NULL); //Get buffer size
3309 if (len)
3310 {
3311 rlist = (WXRGNDATA *) (RGNDATA *)new char[len];
3312 GetRegionData((HRGN) wnd->m_updateRgn,len, (RGNDATA *)rlist);
3313 rp = (void *)(RECT*) ((RGNDATA *)rlist)->Buffer;
3314 rects = ((RGNDATA *)rlist)->rdh.nCount;
3315 }
3316 else
3317 #endif
3318 {
3319 gs_UpdateRect.left = wnd->m_updateRect.x;
3320 gs_UpdateRect.top = wnd->m_updateRect.y;
3321 gs_UpdateRect.right = wnd->m_updateRect.x + wnd->m_updateRect.width;
3322 gs_UpdateRect.bottom = wnd->m_updateRect.y + wnd->m_updateRect.height;
3323 rects = 1;
3324 rp = (void *)&gs_UpdateRect; //Only one available in Win16,32s
3325 }
3326 }
3327
3328 wxUpdateIterator::~wxUpdateIterator(void)
3329 {
3330 #ifdef __WIN32__
3331 #ifndef __win32s__
3332 if (rlist) delete (RGNDATA *) rlist;
3333 #endif
3334 #endif
3335 }
3336
3337 wxUpdateIterator::operator int (void)
3338 {
3339 if (current < rects)
3340 {
3341 return TRUE;
3342 }
3343 else
3344 {
3345 return FALSE;
3346 }
3347 }
3348
3349 wxUpdateIterator* wxUpdateIterator::operator ++(int)
3350 {
3351 current++;
3352 return this;
3353 }
3354
3355 void wxUpdateIterator::GetRect(wxRect *rect)
3356 {
3357 RECT *mswRect = ((RECT *)rp)+current; //ought to error check this...
3358 rect->x = mswRect->left;
3359 rect->y = mswRect->top;
3360 rect->width = mswRect->right - mswRect->left;
3361 rect->height = mswRect->bottom - mswRect->top;
3362 }
3363
3364 int wxUpdateIterator::GetX()
3365 {
3366 return ((RECT*)rp)[current].left;
3367 }
3368
3369 int wxUpdateIterator::GetY()
3370 {
3371 return ((RECT *)rp)[current].top;
3372 }
3373
3374 int wxUpdateIterator::GetW()
3375 {
3376 return ((RECT *)rp)[current].right-GetX();
3377 }
3378
3379 int wxUpdateIterator::GetH()
3380 {
3381 return ((RECT *)rp)[current].bottom-GetY();
3382 }
3383
3384 wxWindow *wxGetActiveWindow(void)
3385 {
3386 HWND hWnd = GetActiveWindow();
3387 if (hWnd != 0)
3388 {
3389 return wxFindWinFromHandle((WXHWND) hWnd);
3390 }
3391 return NULL;
3392 }
3393
3394 // Windows keyboard hook. Allows interception of e.g. F1, ESCAPE
3395 // in active frames and dialogs, regardless of where the focus is.
3396 static HHOOK wxTheKeyboardHook = 0;
3397 static FARPROC wxTheKeyboardHookProc = 0;
3398 int APIENTRY _EXPORT
3399 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam);
3400
3401 void wxSetKeyboardHook(bool doIt)
3402 {
3403 if (doIt)
3404 {
3405 wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
3406 wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
3407 #ifdef __WIN32__
3408 GetCurrentThreadId());
3409 // (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
3410 #else
3411 GetCurrentTask());
3412 #endif
3413 }
3414 else
3415 {
3416 UnhookWindowsHookEx(wxTheKeyboardHook);
3417 FreeProcInstance(wxTheKeyboardHookProc);
3418 }
3419 }
3420
3421 int APIENTRY _EXPORT
3422 wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
3423 {
3424 DWORD hiWord = HIWORD(lParam);
3425 if (nCode != HC_NOREMOVE && ((hiWord & KF_UP) == 0))
3426 {
3427 int id;
3428 if ((id = wxCharCodeMSWToWX(wParam)) != 0)
3429 {
3430 wxKeyEvent event(wxEVT_CHAR_HOOK);
3431 if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
3432 event.m_altDown = TRUE;
3433
3434 event.m_eventObject = NULL;
3435 event.m_keyCode = id;
3436 /* begin Albert's fix for control and shift key 26.5 */
3437 event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
3438 event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
3439 /* end Albert's fix for control and shift key 26.5 */
3440 event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
3441
3442 #if WXWIN_COMPATIBILITY
3443 if ( wxTheApp && wxTheApp->OldOnCharHook(event) )
3444 return 1;
3445 #endif
3446 wxWindow *win = wxGetActiveWindow();
3447 if (win)
3448 {
3449 if (win->GetEventHandler()->ProcessEvent(event))
3450 return 1;
3451 }
3452 else
3453 {
3454 if ( wxTheApp && wxTheApp->ProcessEvent(event) )
3455 return 1;
3456 }
3457 }
3458 }
3459 return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
3460 }
3461
3462 void wxWindow::SetSizeHints(const int minW, const int minH, const int maxW, const int maxH, const int WXUNUSED(incW), const int WXUNUSED(incH))
3463 {
3464 m_minSizeX = minW;
3465 m_minSizeY = minH;
3466 m_maxSizeX = maxW;
3467 m_maxSizeY = maxH;
3468 }
3469
3470 void wxWindow::Centre(const int direction)
3471 {
3472 int x, y, width, height, panel_width, panel_height, new_x, new_y;
3473
3474 wxWindow *father = (wxWindow *)GetParent();
3475 if (!father)
3476 return;
3477
3478 father->GetClientSize(&panel_width, &panel_height);
3479 GetSize(&width, &height);
3480 GetPosition(&x, &y);
3481
3482 new_x = -1;
3483 new_y = -1;
3484
3485 if (direction & wxHORIZONTAL)
3486 new_x = (int)((panel_width - width)/2);
3487
3488 if (direction & wxVERTICAL)
3489 new_y = (int)((panel_height - height)/2);
3490
3491 SetSize(new_x, new_y, -1, -1);
3492
3493 }
3494
3495 /* TODO (maybe)
3496 void wxWindow::OnPaint(void)
3497 {
3498 PaintSelectionHandles();
3499 }
3500 */
3501
3502 void wxWindow::WarpPointer (const int x_pos, const int y_pos)
3503 {
3504 // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
3505 // pixel coordinates, relatives to the canvas -- So, we first need to
3506 // substract origin of the window, then convert to screen position
3507
3508 int x = x_pos; int y = y_pos;
3509 /* Leave this to the app to decide (and/or wxScrolledWindow)
3510 x -= m_xScrollPosition * m_xScrollPixelsPerLine;
3511 y -= m_yScrollPosition * m_yScrollPixelsPerLine;
3512 */
3513 RECT rect;
3514 GetWindowRect ((HWND) GetHWND(), &rect);
3515
3516 x += rect.left;
3517 y += rect.top;
3518
3519 SetCursorPos (x, y);
3520 }
3521
3522 void wxWindow::MSWDeviceToLogical (float *x, float *y) const
3523 {
3524 // TODO
3525 // Do we have a SetUserScale in wxWindow too, so we can
3526 // get mouse events scaled?
3527 /*
3528 if (m_windowDC)
3529 {
3530 *x = m_windowDC->DeviceToLogicalX ((int) *x);
3531 *y = m_windowDC->DeviceToLogicalY ((int) *y);
3532 }
3533 */
3534 }
3535
3536 bool wxWindow::MSWOnEraseBkgnd (const WXHDC pDC)
3537 {
3538 wxDC dc ;
3539
3540 dc.SetHDC(pDC);
3541 dc.SetWindow(this);
3542 dc.BeginDrawing();
3543
3544 wxEraseEvent event(m_windowId, &dc);
3545 event.m_eventObject = this;
3546 if (!GetEventHandler()->ProcessEvent(event))
3547 {
3548 dc.EndDrawing();
3549 dc.SelectOldObjects(pDC);
3550 return FALSE;
3551 }
3552 else
3553 {
3554 dc.EndDrawing();
3555 dc.SelectOldObjects(pDC);
3556 }
3557
3558 dc.SetHDC((WXHDC) NULL);
3559 return TRUE;
3560 }
3561
3562 void wxWindow::OnEraseBackground(wxEraseEvent& event)
3563 {
3564 RECT rect;
3565 ::GetClientRect((HWND) GetHWND(), &rect);
3566
3567 HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
3568 int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
3569
3570 // ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
3571 ::FillRect ((HDC) event.GetDC()->GetHDC(), &rect, hBrush);
3572 ::DeleteObject(hBrush);
3573 ::SetMapMode((HDC) event.GetDC()->GetHDC(), mode);
3574 /*
3575 // Less efficient version (and doesn't account for scrolling)
3576 int w, h;
3577 GetClientSize(& w, & h);
3578 wxBrush *brush = wxTheBrushList->FindOrCreateBrush(& GetBackgroundColour(), wxSOLID);
3579 event.GetDC()->SetBrush(brush);
3580 event.GetDC()->SetPen(wxTRANSPARENT_PEN);
3581
3582 event.GetDC()->DrawRectangle(0, 0, w+1, h+1);
3583 */
3584 }
3585
3586 #if WXWIN_COMPATIBILITY
3587 void wxWindow::SetScrollRange(const int orient, const int range, const bool refresh)
3588 {
3589 #if defined(__WIN95__)
3590
3591 int range1 = range;
3592
3593 // Try to adjust the range to cope with page size > 1
3594 // - a Windows API quirk
3595 int pageSize = GetScrollPage(orient);
3596 if ( pageSize > 1 && range > 0)
3597 {
3598 range1 += (pageSize - 1);
3599 }
3600
3601 SCROLLINFO info;
3602 int dir;
3603
3604 if (orient == wxHORIZONTAL) {
3605 dir = SB_HORZ;
3606 } else {
3607 dir = SB_VERT;
3608 }
3609
3610 info.cbSize = sizeof(SCROLLINFO);
3611 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3612 info.nMin = 0;
3613 info.nMax = range1;
3614 info.nPos = 0;
3615 info.fMask = SIF_RANGE | SIF_PAGE;
3616
3617 HWND hWnd = (HWND) GetHWND();
3618 if (hWnd)
3619 ::SetScrollInfo(hWnd, dir, &info, refresh);
3620 #else
3621 int wOrient ;
3622 if (orient == wxHORIZONTAL)
3623 wOrient = SB_HORZ;
3624 else
3625 wOrient = SB_VERT;
3626
3627 HWND hWnd = (HWND) GetHWND();
3628 if (hWnd)
3629 ::SetScrollRange(hWnd, wOrient, 0, range, refresh);
3630 #endif
3631 }
3632
3633 void wxWindow::SetScrollPage(const int orient, const int page, const bool refresh)
3634 {
3635 #if defined(__WIN95__)
3636 SCROLLINFO info;
3637 int dir;
3638
3639 if (orient == wxHORIZONTAL) {
3640 dir = SB_HORZ;
3641 m_xThumbSize = page;
3642 } else {
3643 dir = SB_VERT;
3644 m_yThumbSize = page;
3645 }
3646
3647 info.cbSize = sizeof(SCROLLINFO);
3648 info.nPage = page;
3649 info.nMin = 0;
3650 info.fMask = SIF_PAGE ;
3651
3652 HWND hWnd = (HWND) GetHWND();
3653 if (hWnd)
3654 ::SetScrollInfo(hWnd, dir, &info, refresh);
3655 #else
3656 if (orient == wxHORIZONTAL)
3657 m_xThumbSize = page;
3658 else
3659 m_yThumbSize = page;
3660 #endif
3661 }
3662
3663 int wxWindow::OldGetScrollRange(const int orient) const
3664 {
3665 int wOrient ;
3666 if (orient == wxHORIZONTAL)
3667 wOrient = SB_HORZ;
3668 else
3669 wOrient = SB_VERT;
3670
3671 #if __WATCOMC__ && defined(__WINDOWS_386__)
3672 short minPos, maxPos;
3673 #else
3674 int minPos, maxPos;
3675 #endif
3676 HWND hWnd = (HWND) GetHWND();
3677 if (hWnd)
3678 {
3679 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3680 #if defined(__WIN95__)
3681 // Try to adjust the range to cope with page size > 1
3682 // - a Windows API quirk
3683 int pageSize = GetScrollPage(orient);
3684 if ( pageSize > 1 )
3685 {
3686 maxPos -= (pageSize - 1);
3687 }
3688 #endif
3689 return maxPos;
3690 }
3691 else
3692 return 0;
3693 }
3694
3695 int wxWindow::GetScrollPage(const int orient) const
3696 {
3697 if (orient == wxHORIZONTAL)
3698 return m_xThumbSize;
3699 else
3700 return m_yThumbSize;
3701 }
3702 #endif
3703
3704 int wxWindow::GetScrollPos(const int orient) const
3705 {
3706 int wOrient ;
3707 if (orient == wxHORIZONTAL)
3708 wOrient = SB_HORZ;
3709 else
3710 wOrient = SB_VERT;
3711 HWND hWnd = (HWND) GetHWND();
3712 if (hWnd)
3713 {
3714 return ::GetScrollPos(hWnd, wOrient);
3715 }
3716 else
3717 return 0;
3718 }
3719
3720 // This now returns the whole range, not just the number
3721 // of positions that we can scroll.
3722 int wxWindow::GetScrollRange(const int orient) const
3723 {
3724 int wOrient ;
3725 if (orient == wxHORIZONTAL)
3726 wOrient = SB_HORZ;
3727 else
3728 wOrient = SB_VERT;
3729
3730 #if __WATCOMC__ && defined(__WINDOWS_386__)
3731 short minPos, maxPos;
3732 #else
3733 int minPos, maxPos;
3734 #endif
3735 HWND hWnd = (HWND) GetHWND();
3736 if (hWnd)
3737 {
3738 ::GetScrollRange(hWnd, wOrient, &minPos, &maxPos);
3739 #if defined(__WIN95__)
3740 // Try to adjust the range to cope with page size > 1
3741 // - a Windows API quirk
3742 int pageSize = GetScrollPage(orient);
3743 if ( pageSize > 1 )
3744 {
3745 maxPos -= (pageSize - 1);
3746 }
3747 // October 10th: new range concept.
3748 maxPos += pageSize;
3749 #endif
3750
3751 return maxPos;
3752 }
3753 else
3754 return 0;
3755 }
3756
3757 int wxWindow::GetScrollThumb(const int orient) const
3758 {
3759 if (orient == wxHORIZONTAL)
3760 return m_xThumbSize;
3761 else
3762 return m_yThumbSize;
3763 }
3764
3765 void wxWindow::SetScrollPos(const int orient, const int pos, const bool refresh)
3766 {
3767 #if defined(__WIN95__)
3768 SCROLLINFO info;
3769 int dir;
3770
3771 if (orient == wxHORIZONTAL) {
3772 dir = SB_HORZ;
3773 } else {
3774 dir = SB_VERT;
3775 }
3776
3777 info.cbSize = sizeof(SCROLLINFO);
3778 info.nPage = 0;
3779 info.nMin = 0;
3780 info.nPos = pos;
3781 info.fMask = SIF_POS ;
3782
3783 HWND hWnd = (HWND) GetHWND();
3784 if (hWnd)
3785 ::SetScrollInfo(hWnd, dir, &info, refresh);
3786 #else
3787 int wOrient ;
3788 if (orient == wxHORIZONTAL)
3789 wOrient = SB_HORZ;
3790 else
3791 wOrient = SB_VERT;
3792
3793 HWND hWnd = (HWND) GetHWND();
3794 if (hWnd)
3795 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3796 #endif
3797 }
3798
3799 // New function that will replace some of the above.
3800 void wxWindow::SetScrollbar(const int orient, const int pos, const int thumbVisible,
3801 const int range, const bool refresh)
3802 {
3803 /*
3804 SetScrollPage(orient, thumbVisible, FALSE);
3805
3806 int oldRange = range - thumbVisible ;
3807 SetScrollRange(orient, oldRange, FALSE);
3808
3809 SetScrollPos(orient, pos, refresh);
3810 */
3811 #if defined(__WIN95__)
3812 int oldRange = range - thumbVisible ;
3813
3814 int range1 = oldRange;
3815
3816 // Try to adjust the range to cope with page size > 1
3817 // - a Windows API quirk
3818 int pageSize = thumbVisible;
3819 if ( pageSize > 1 && range > 0)
3820 {
3821 range1 += (pageSize - 1);
3822 }
3823
3824 SCROLLINFO info;
3825 int dir;
3826
3827 if (orient == wxHORIZONTAL) {
3828 dir = SB_HORZ;
3829 } else {
3830 dir = SB_VERT;
3831 }
3832
3833 info.cbSize = sizeof(SCROLLINFO);
3834 info.nPage = pageSize; // Have to set this, or scrollbar goes awry
3835 info.nMin = 0;
3836 info.nMax = range1;
3837 info.nPos = pos;
3838 info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
3839
3840 HWND hWnd = (HWND) GetHWND();
3841 if (hWnd)
3842 ::SetScrollInfo(hWnd, dir, &info, refresh);
3843 #else
3844 int wOrient ;
3845 if (orient == wxHORIZONTAL)
3846 wOrient = SB_HORZ;
3847 else
3848 wOrient = SB_VERT;
3849
3850 HWND hWnd = (HWND) GetHWND();
3851 if (hWnd)
3852 {
3853 ::SetScrollRange(hWnd, wOrient, 0, range, FALSE);
3854 ::SetScrollPos(hWnd, wOrient, pos, refresh);
3855 }
3856 #endif
3857 if (orient == wxHORIZONTAL) {
3858 m_xThumbSize = thumbVisible;
3859 } else {
3860 m_yThumbSize = thumbVisible;
3861 }
3862 }
3863
3864 void wxWindow::ScrollWindow(const int dx, const int dy, const wxRectangle *rect)
3865 {
3866 RECT rect2;
3867 if ( rect )
3868 {
3869 rect2.left = rect->x;
3870 rect2.top = rect->y;
3871 rect2.right = rect->x + rect->width;
3872 rect2.bottom = rect->y + rect->height;
3873 }
3874
3875 if ( rect )
3876 ::ScrollWindow((HWND) GetHWND(), dx, dy, &rect2, NULL);
3877 else
3878 ::ScrollWindow((HWND) GetHWND(), dx, dy, NULL, NULL);
3879 }
3880
3881 void wxWindow::OnSize(wxSizeEvent& event)
3882 {
3883 Default();
3884 #if USE_CONSTRAINTS
3885 if (GetAutoLayout())
3886 Layout();
3887 #endif
3888 }
3889
3890 /*
3891 void wxWindow::CalcScrolledPosition(const int x, const int y, int *xx, int *yy) const
3892 {
3893 *xx = x;
3894 *yy = y;
3895 }
3896
3897 void wxWindow::CalcUnscrolledPosition(const int x, const int y, float *xx, float *yy) const
3898 {
3899 *xx = x;
3900 *yy = y;
3901 }
3902 */
3903
3904 void wxWindow::SetFont(const wxFont& font)
3905 {
3906 // Decrement the usage count of the old label font
3907 // (we may be able to free it up)
3908 // if (GetFont()->Ok())
3909 // GetFont()->ReleaseResource();
3910
3911 m_windowFont = font;
3912
3913 if (!m_windowFont.Ok())
3914 return;
3915
3916 // m_windowFont.UseResource();
3917
3918 HWND hWnd = (HWND) GetHWND();
3919 if (hWnd != 0)
3920 {
3921 // m_windowFont.RealizeResource();
3922
3923 if (m_windowFont.GetResourceHandle())
3924 SendMessage(hWnd, WM_SETFONT,
3925 (WPARAM)m_windowFont.GetResourceHandle(),TRUE);
3926 }
3927 }
3928
3929 void wxWindow::SubclassWin(WXHWND hWnd)
3930 {
3931 wxAssociateWinWithHandle((HWND)hWnd, this);
3932
3933 m_oldWndProc = (WXFARPROC) GetWindowLong((HWND) hWnd, GWL_WNDPROC);
3934 SetWindowLong((HWND) hWnd, GWL_WNDPROC, (LONG) wxWndProc);
3935 }
3936
3937 void wxWindow::UnsubclassWin(void)
3938 {
3939 wxRemoveHandleAssociation(this);
3940
3941 // Restore old Window proc
3942 if ((HWND) GetHWND())
3943 {
3944 FARPROC farProc = (FARPROC) GetWindowLong((HWND) GetHWND(), GWL_WNDPROC);
3945 if ((m_oldWndProc != 0) && (farProc != (FARPROC) m_oldWndProc))
3946 {
3947 SetWindowLong((HWND) GetHWND(), GWL_WNDPROC, (LONG) m_oldWndProc);
3948 m_oldWndProc = 0;
3949 }
3950 }
3951 }
3952
3953 // Make a Windows extended style from the given wxWindows window style
3954 WXDWORD wxWindow::MakeExtendedStyle(long style, bool eliminateBorders)
3955 {
3956 WXDWORD exStyle = 0;
3957 if ( style & wxTRANSPARENT_WINDOW )
3958 exStyle |= WS_EX_TRANSPARENT ;
3959
3960 if ( !eliminateBorders )
3961 {
3962 if ( style & wxSUNKEN_BORDER )
3963 exStyle |= WS_EX_CLIENTEDGE ;
3964 if ( style & wxDOUBLE_BORDER )
3965 exStyle |= WS_EX_DLGMODALFRAME ;
3966 #if defined(__WIN95__)
3967 if ( style & wxRAISED_BORDER )
3968 exStyle |= WS_EX_WINDOWEDGE ;
3969 if ( style & wxSTATIC_BORDER )
3970 exStyle |= WS_EX_STATICEDGE ;
3971 #endif
3972 }
3973 return exStyle;
3974 }
3975
3976 // Determines whether native 3D effects or CTL3D should be used,
3977 // applying a default border style if required, and returning an extended
3978 // style to pass to CreateWindowEx.
3979 WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
3980 {
3981 // If matches certain criteria, then assume no 3D effects
3982 // unless specifically requested (dealt with in MakeExtendedStyle)
3983 if ( !GetParent() || !IsKindOf(CLASSINFO(wxControl)) || (m_windowStyle & wxNO_BORDER) )
3984 {
3985 *want3D = FALSE;
3986 return MakeExtendedStyle(m_windowStyle, FALSE);
3987 }
3988
3989 // Determine whether we should be using 3D effects or not.
3990 bool nativeBorder = FALSE; // by default, we don't want a Win95 effect
3991
3992 // 1) App can specify global 3D effects
3993 *want3D = wxTheApp->GetAuto3D();
3994
3995 // 2) If the parent is being drawn with user colours, or simple border specified,
3996 // switch effects off. TODO: replace wxUSER_COLOURS with wxNO_3D
3997 if (GetParent() && (GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS) || (m_windowStyle & wxSIMPLE_BORDER))
3998 *want3D = FALSE;
3999
4000 // 3) Control can override this global setting by defining
4001 // a border style, e.g. wxSUNKEN_BORDER
4002 if (m_windowStyle & wxSUNKEN_BORDER )
4003 *want3D = TRUE;
4004
4005 // 4) If it's a special border, CTL3D can't cope so we want a native border
4006 if ( (m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
4007 (m_windowStyle & wxSTATIC_BORDER) )
4008 {
4009 *want3D = TRUE;
4010 nativeBorder = TRUE;
4011 }
4012
4013 // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
4014 // effects from extended style
4015 #if CTL3D
4016 if ( *want3D )
4017 nativeBorder = FALSE;
4018 #endif
4019
4020 DWORD exStyle = MakeExtendedStyle(m_windowStyle, !nativeBorder);
4021
4022 // If we want 3D, but haven't specified a border here,
4023 // apply the default border style specified.
4024 // TODO what about non-Win95 WIN32? Does it have borders?
4025 #if defined(__WIN95__) && !CTL3D
4026 if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
4027 (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
4028 exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
4029 #endif
4030
4031 return exStyle;
4032 }
4033
4034 #if WXWIN_COMPATIBILITY
4035 void wxWindow::OldOnPaint(void)
4036 {
4037 wxPaintEvent event(m_windowId);
4038 event.m_eventObject = this;
4039 if (!GetEventHandler()->ProcessEvent(event))
4040 Default();
4041 };
4042
4043 void wxWindow::OldOnSize(int w, int h)
4044 {
4045 wxSizeEvent event(wxSize(w, h), m_windowId);
4046 event.m_eventObject = this;
4047 if (!GetEventHandler()->ProcessEvent(event))
4048 Default();
4049 };
4050
4051 void wxWindow::OldOnMouseEvent(wxMouseEvent& event)
4052 {
4053 if (!GetEventHandler()->ProcessEvent(event))
4054 Default();
4055 };
4056
4057 void wxWindow::OldOnChar(wxKeyEvent& event)
4058 {
4059 if (!GetEventHandler()->ProcessEvent(event))
4060 Default();
4061 };
4062
4063 void wxWindow::OldOnSetFocus(void)
4064 {
4065 wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
4066 event.m_eventObject = this;
4067 if (!GetEventHandler()->ProcessEvent(event))
4068 Default();
4069 };
4070
4071 void wxWindow::OldOnKillFocus(void)
4072 {
4073 wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
4074 event.m_eventObject = this;
4075 if (!GetEventHandler()->ProcessEvent(event))
4076 Default();
4077 };
4078 #endif
4079
4080 void wxWindow::OnChar(wxKeyEvent& event)
4081 {
4082 bool isVirtual;
4083 int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
4084
4085 if ( id == -1 )
4086 id= m_lastWParam;
4087
4088 if ( !event.ControlDown() )
4089 (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
4090 }
4091
4092 void wxWindow::OnPaint(wxPaintEvent& event)
4093 {
4094 Default();
4095 }
4096
4097 bool wxWindow::IsEnabled(void) const
4098 {
4099 return (::IsWindowEnabled((HWND) GetHWND()) != 0);
4100 }
4101
4102 // Dialog support: override these and call
4103 // base class members to add functionality
4104 // that can't be done using validators.
4105 // NOTE: these functions assume that controls
4106 // are direct children of this window, not grandchildren
4107 // or other levels of descendant.
4108
4109 // Transfer values to controls. If returns FALSE,
4110 // it's an application error (pops up a dialog)
4111 bool wxWindow::TransferDataToWindow(void)
4112 {
4113 wxNode *node = GetChildren()->First();
4114 while ( node )
4115 {
4116 wxWindow *child = (wxWindow *)node->Data();
4117 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
4118 !child->GetValidator()->TransferToWindow() )
4119 {
4120 wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
4121 return FALSE;
4122 }
4123
4124 node = node->Next();
4125 }
4126 return TRUE;
4127 }
4128
4129 // Transfer values from controls. If returns FALSE,
4130 // validation failed: don't quit
4131 bool wxWindow::TransferDataFromWindow(void)
4132 {
4133 wxNode *node = GetChildren()->First();
4134 while ( node )
4135 {
4136 wxWindow *child = (wxWindow *)node->Data();
4137 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
4138 {
4139 return FALSE;
4140 }
4141
4142 node = node->Next();
4143 }
4144 return TRUE;
4145 }
4146
4147 bool wxWindow::Validate(void)
4148 {
4149 wxNode *node = GetChildren()->First();
4150 while ( node )
4151 {
4152 wxWindow *child = (wxWindow *)node->Data();
4153 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this) )
4154 {
4155 return FALSE;
4156 }
4157
4158 node = node->Next();
4159 }
4160 return TRUE;
4161 }
4162
4163 // Get the window with the focus
4164 wxWindow *wxWindow::FindFocus(void)
4165 {
4166 HWND hWnd = ::GetFocus();
4167 if ( hWnd )
4168 {
4169 return wxFindWinFromHandle((WXHWND) hWnd);
4170 }
4171 return NULL;
4172 }
4173
4174 void wxWindow::AddChild(wxWindow *child)
4175 {
4176 GetChildren()->Append(child);
4177 child->m_windowParent = this;
4178 }
4179
4180 void wxWindow::RemoveChild(wxWindow *child)
4181 {
4182 if (GetChildren())
4183 GetChildren()->DeleteObject(child);
4184 child->m_windowParent = NULL;
4185 }
4186
4187 void wxWindow::DestroyChildren(void)
4188 {
4189 if (GetChildren()) {
4190 wxNode *node;
4191 while ((node = GetChildren()->First()) != (wxNode *)NULL) {
4192 wxWindow *child;
4193 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) {
4194 delete child;
4195 if ( GetChildren()->Member(child) )
4196 delete node;
4197 }
4198 } /* while */
4199 }
4200 }
4201
4202 void wxWindow::MakeModal(const bool modal)
4203 {
4204 // Disable all other windows
4205 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
4206 {
4207 wxNode *node = wxTopLevelWindows.First();
4208 while (node)
4209 {
4210 wxWindow *win = (wxWindow *)node->Data();
4211 if (win != this)
4212 win->Enable(!modal);
4213
4214 node = node->Next();
4215 }
4216 }
4217 }
4218
4219 // If nothing defined for this, try the parent.
4220 // E.g. we may be a button loaded from a resource, with no callback function
4221 // defined.
4222 void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
4223 {
4224 if (GetEventHandler()->ProcessEvent(event) )
4225 return;
4226 if (m_windowParent)
4227 m_windowParent->GetEventHandler()->OnCommand(win, event);
4228 }
4229
4230 void wxWindow::SetConstraints(wxLayoutConstraints *c)
4231 {
4232 if (m_constraints)
4233 {
4234 UnsetConstraints(m_constraints);
4235 delete m_constraints;
4236 }
4237 m_constraints = c;
4238 if (m_constraints)
4239 {
4240 // Make sure other windows know they're part of a 'meaningful relationship'
4241 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
4242 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4243 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
4244 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4245 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
4246 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4247 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
4248 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4249 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
4250 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4251 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
4252 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4253 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
4254 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4255 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
4256 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
4257 }
4258 }
4259
4260 // This removes any dangling pointers to this window
4261 // in other windows' constraintsInvolvedIn lists.
4262 void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
4263 {
4264 if (c)
4265 {
4266 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
4267 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4268 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
4269 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4270 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
4271 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4272 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
4273 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4274 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
4275 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4276 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
4277 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4278 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
4279 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4280 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
4281 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
4282 }
4283 }
4284
4285 // Back-pointer to other windows we're involved with, so if we delete
4286 // this window, we must delete any constraints we're involved with.
4287 void wxWindow::AddConstraintReference(wxWindow *otherWin)
4288 {
4289 if (!m_constraintsInvolvedIn)
4290 m_constraintsInvolvedIn = new wxList;
4291 if (!m_constraintsInvolvedIn->Member(otherWin))
4292 m_constraintsInvolvedIn->Append(otherWin);
4293 }
4294
4295 // REMOVE back-pointer to other windows we're involved with.
4296 void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
4297 {
4298 if (m_constraintsInvolvedIn)
4299 m_constraintsInvolvedIn->DeleteObject(otherWin);
4300 }
4301
4302 // Reset any constraints that mention this window
4303 void wxWindow::DeleteRelatedConstraints(void)
4304 {
4305 if (m_constraintsInvolvedIn)
4306 {
4307 wxNode *node = m_constraintsInvolvedIn->First();
4308 while (node)
4309 {
4310 wxWindow *win = (wxWindow *)node->Data();
4311 wxNode *next = node->Next();
4312 wxLayoutConstraints *constr = win->GetConstraints();
4313
4314 // Reset any constraints involving this window
4315 if (constr)
4316 {
4317 constr->left.ResetIfWin((wxWindow *)this);
4318 constr->top.ResetIfWin((wxWindow *)this);
4319 constr->right.ResetIfWin((wxWindow *)this);
4320 constr->bottom.ResetIfWin((wxWindow *)this);
4321 constr->width.ResetIfWin((wxWindow *)this);
4322 constr->height.ResetIfWin((wxWindow *)this);
4323 constr->centreX.ResetIfWin((wxWindow *)this);
4324 constr->centreY.ResetIfWin((wxWindow *)this);
4325 }
4326 delete node;
4327 node = next;
4328 }
4329 delete m_constraintsInvolvedIn;
4330 m_constraintsInvolvedIn = NULL;
4331 }
4332 }
4333
4334 void wxWindow::SetSizer(wxSizer *sizer)
4335 {
4336 m_windowSizer = sizer;
4337 if (sizer)
4338 sizer->SetSizerParent((wxWindow *)this);
4339 }
4340
4341 /*
4342 * New version
4343 */
4344
4345 bool wxWindow::Layout(void)
4346 {
4347 if (GetConstraints())
4348 {
4349 int w, h;
4350 GetClientSize(&w, &h);
4351 GetConstraints()->width.SetValue(w);
4352 GetConstraints()->height.SetValue(h);
4353 }
4354
4355 // If top level (one sizer), evaluate the sizer's constraints.
4356 if (GetSizer())
4357 {
4358 int noChanges;
4359 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
4360 GetSizer()->LayoutPhase1(&noChanges);
4361 GetSizer()->LayoutPhase2(&noChanges);
4362 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
4363 return TRUE;
4364 }
4365 else
4366 {
4367 // Otherwise, evaluate child constraints
4368 ResetConstraints(); // Mark all constraints as unevaluated
4369 DoPhase(1); // Just one phase need if no sizers involved
4370 DoPhase(2);
4371 SetConstraintSizes(); // Recursively set the real window sizes
4372 }
4373 return TRUE;
4374 }
4375
4376
4377 // Do a phase of evaluating constraints:
4378 // the default behaviour. wxSizers may do a similar
4379 // thing, but also impose their own 'constraints'
4380 // and order the evaluation differently.
4381 bool wxWindow::LayoutPhase1(int *noChanges)
4382 {
4383 wxLayoutConstraints *constr = GetConstraints();
4384 if (constr)
4385 {
4386 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
4387 }
4388 else
4389 return TRUE;
4390 }
4391
4392 bool wxWindow::LayoutPhase2(int *noChanges)
4393 {
4394 *noChanges = 0;
4395
4396 // Layout children
4397 DoPhase(1);
4398 DoPhase(2);
4399 return TRUE;
4400 }
4401
4402 // Do a phase of evaluating child constraints
4403 bool wxWindow::DoPhase(const int phase)
4404 {
4405 int noIterations = 0;
4406 int maxIterations = 500;
4407 int noChanges = 1;
4408 int noFailures = 0;
4409 wxList succeeded;
4410 while ((noChanges > 0) && (noIterations < maxIterations))
4411 {
4412 noChanges = 0;
4413 noFailures = 0;
4414 wxNode *node = GetChildren()->First();
4415 while (node)
4416 {
4417 wxWindow *child = (wxWindow *)node->Data();
4418 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
4419 {
4420 wxLayoutConstraints *constr = child->GetConstraints();
4421 if (constr)
4422 {
4423 if (succeeded.Member(child))
4424 {
4425 }
4426 else
4427 {
4428 int tempNoChanges = 0;
4429 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
4430 noChanges += tempNoChanges;
4431 if (success)
4432 {
4433 succeeded.Append(child);
4434 }
4435 }
4436 }
4437 }
4438 node = node->Next();
4439 }
4440 noIterations ++;
4441 }
4442 return TRUE;
4443 }
4444
4445 void wxWindow::ResetConstraints(void)
4446 {
4447 wxLayoutConstraints *constr = GetConstraints();
4448 if (constr)
4449 {
4450 constr->left.SetDone(FALSE);
4451 constr->top.SetDone(FALSE);
4452 constr->right.SetDone(FALSE);
4453 constr->bottom.SetDone(FALSE);
4454 constr->width.SetDone(FALSE);
4455 constr->height.SetDone(FALSE);
4456 constr->centreX.SetDone(FALSE);
4457 constr->centreY.SetDone(FALSE);
4458 }
4459 wxNode *node = GetChildren()->First();
4460 while (node)
4461 {
4462 wxWindow *win = (wxWindow *)node->Data();
4463 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
4464 win->ResetConstraints();
4465 node = node->Next();
4466 }
4467 }
4468
4469 // Need to distinguish between setting the 'fake' size for
4470 // windows and sizers, and setting the real values.
4471 void wxWindow::SetConstraintSizes(const bool recurse)
4472 {
4473 wxLayoutConstraints *constr = GetConstraints();
4474 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
4475 constr->width.GetDone() && constr->height.GetDone())
4476 {
4477 int x = constr->left.GetValue();
4478 int y = constr->top.GetValue();
4479 int w = constr->width.GetValue();
4480 int h = constr->height.GetValue();
4481
4482 // If we don't want to resize this window, just move it...
4483 if ((constr->width.GetRelationship() != wxAsIs) ||
4484 (constr->height.GetRelationship() != wxAsIs))
4485 {
4486 // Calls Layout() recursively. AAAGH. How can we stop that.
4487 // Simply take Layout() out of non-top level OnSizes.
4488 SizerSetSize(x, y, w, h);
4489 }
4490 else
4491 {
4492 SizerMove(x, y);
4493 }
4494 }
4495 else if (constr)
4496 {
4497 char *windowClass = this->GetClassInfo()->GetClassName();
4498
4499 wxString winName;
4500 if (GetName() == "")
4501 winName = "unnamed";
4502 else
4503 winName = GetName();
4504 wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
4505 if (!constr->left.GetDone())
4506 wxDebugMsg(" unsatisfied 'left' constraint.\n");
4507 if (!constr->right.GetDone())
4508 wxDebugMsg(" unsatisfied 'right' constraint.\n");
4509 if (!constr->width.GetDone())
4510 wxDebugMsg(" unsatisfied 'width' constraint.\n");
4511 if (!constr->height.GetDone())
4512 wxDebugMsg(" unsatisfied 'height' constraint.\n");
4513 wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
4514 }
4515
4516 if (recurse)
4517 {
4518 wxNode *node = GetChildren()->First();
4519 while (node)
4520 {
4521 wxWindow *win = (wxWindow *)node->Data();
4522 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
4523 win->SetConstraintSizes();
4524 node = node->Next();
4525 }
4526 }
4527 }
4528
4529 // This assumes that all sizers are 'on' the same
4530 // window, i.e. the parent of this window.
4531 void wxWindow::TransformSizerToActual(int *x, int *y) const
4532 {
4533 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
4534 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
4535 return;
4536
4537 int xp, yp;
4538 m_sizerParent->GetPosition(&xp, &yp);
4539 m_sizerParent->TransformSizerToActual(&xp, &yp);
4540 *x += xp;
4541 *y += yp;
4542 }
4543
4544 void wxWindow::SizerSetSize(const int x, const int y, const int w, const int h)
4545 {
4546 int xx = x;
4547 int yy = y;
4548 TransformSizerToActual(&xx, &yy);
4549 SetSize(xx, yy, w, h);
4550 }
4551
4552 void wxWindow::SizerMove(const int x, const int y)
4553 {
4554 int xx = x;
4555 int yy = y;
4556 TransformSizerToActual(&xx, &yy);
4557 Move(xx, yy);
4558 }
4559
4560 // Only set the size/position of the constraint (if any)
4561 void wxWindow::SetSizeConstraint(const int x, const int y, const int w, const int h)
4562 {
4563 wxLayoutConstraints *constr = GetConstraints();
4564 if (constr)
4565 {
4566 if (x != -1)
4567 {
4568 constr->left.SetValue(x);
4569 constr->left.SetDone(TRUE);
4570 }
4571 if (y != -1)
4572 {
4573 constr->top.SetValue(y);
4574 constr->top.SetDone(TRUE);
4575 }
4576 if (w != -1)
4577 {
4578 constr->width.SetValue(w);
4579 constr->width.SetDone(TRUE);
4580 }
4581 if (h != -1)
4582 {
4583 constr->height.SetValue(h);
4584 constr->height.SetDone(TRUE);
4585 }
4586 }
4587 }
4588
4589 void wxWindow::MoveConstraint(const int x, const int y)
4590 {
4591 wxLayoutConstraints *constr = GetConstraints();
4592 if (constr)
4593 {
4594 if (x != -1)
4595 {
4596 constr->left.SetValue(x);
4597 constr->left.SetDone(TRUE);
4598 }
4599 if (y != -1)
4600 {
4601 constr->top.SetValue(y);
4602 constr->top.SetDone(TRUE);
4603 }
4604 }
4605 }
4606
4607 void wxWindow::GetSizeConstraint(int *w, int *h) const
4608 {
4609 wxLayoutConstraints *constr = GetConstraints();
4610 if (constr)
4611 {
4612 *w = constr->width.GetValue();
4613 *h = constr->height.GetValue();
4614 }
4615 else
4616 GetSize(w, h);
4617 }
4618
4619 void wxWindow::GetClientSizeConstraint(int *w, int *h) const
4620 {
4621 wxLayoutConstraints *constr = GetConstraints();
4622 if (constr)
4623 {
4624 *w = constr->width.GetValue();
4625 *h = constr->height.GetValue();
4626 }
4627 else
4628 GetClientSize(w, h);
4629 }
4630
4631 void wxWindow::GetPositionConstraint(int *x, int *y) const
4632 {
4633 wxLayoutConstraints *constr = GetConstraints();
4634 if (constr)
4635 {
4636 *x = constr->left.GetValue();
4637 *y = constr->top.GetValue();
4638 }
4639 else
4640 GetPosition(x, y);
4641 }
4642
4643 bool wxWindow::Close(const bool force)
4644 {
4645 // Let's generalise it to work the same for any window.
4646 /*
4647 if (!IsKindOf(CLASSINFO(wxDialog)) && !IsKindOf(CLASSINFO(wxFrame)))
4648 {
4649 this->Destroy();
4650 return TRUE;
4651 }
4652 */
4653
4654 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
4655 event.SetEventObject(this);
4656 event.SetForce(force);
4657
4658 return GetEventHandler()->ProcessEvent(event);
4659
4660 /*
4661 if ( !force && event.GetVeto() )
4662 return FALSE;
4663
4664 Show(FALSE);
4665
4666 if (!wxPendingDelete.Member(this))
4667 wxPendingDelete.Append(this);
4668
4669 return TRUE;
4670 */
4671 }
4672
4673 wxObject* wxWindow::GetChild(const int number) const
4674 {
4675 // Return a pointer to the Nth object in the Panel
4676 if (!GetChildren())
4677 return(NULL) ;
4678 wxNode *node = GetChildren()->First();
4679 int n = number;
4680 while (node && n--)
4681 node = node->Next() ;
4682 if (node)
4683 {
4684 wxObject *obj = (wxObject *)node->Data();
4685 return(obj) ;
4686 }
4687 else
4688 return NULL ;
4689 }
4690
4691 void wxWindow::OnDefaultAction(wxControl *initiatingItem)
4692 {
4693 if (initiatingItem->IsKindOf(CLASSINFO(wxListBox)) && initiatingItem->GetCallback())
4694 {
4695 wxListBox *lbox = (wxListBox *)initiatingItem;
4696 wxCommandEvent event(wxEVENT_TYPE_LISTBOX_DCLICK_COMMAND);
4697 event.m_commandInt = -1;
4698 if ((lbox->GetWindowStyleFlag() & wxLB_MULTIPLE) == 0)
4699 {
4700 event.m_commandString = copystring(lbox->GetStringSelection());
4701 event.m_commandInt = lbox->GetSelection();
4702 event.m_clientData = lbox->wxListBox::GetClientData(event.m_commandInt);
4703 }
4704 event.m_eventObject = lbox;
4705
4706 lbox->ProcessCommand(event);
4707
4708 if (event.m_commandString)
4709 delete[] event.m_commandString;
4710 return;
4711 }
4712
4713 wxButton *but = GetDefaultItem();
4714 if (but)
4715 {
4716 wxCommandEvent event(wxEVENT_TYPE_BUTTON_COMMAND);
4717 but->Command(event);
4718 }
4719 }
4720
4721 void wxWindow::Clear(void)
4722 {
4723 wxClientDC dc(this);
4724 wxBrush brush(GetBackgroundColour(), wxSOLID);
4725 dc.SetBackground(brush);
4726 dc.Clear();
4727 }
4728
4729 // Fits the panel around the items
4730 void wxWindow::Fit(void)
4731 {
4732 int maxX = 0;
4733 int maxY = 0;
4734 wxNode *node = GetChildren()->First();
4735 while ( node )
4736 {
4737 wxWindow *win = (wxWindow *)node->Data();
4738 int wx, wy, ww, wh;
4739 win->GetPosition(&wx, &wy);
4740 win->GetSize(&ww, &wh);
4741 if ( wx + ww > maxX )
4742 maxX = wx + ww;
4743 if ( wy + wh > maxY )
4744 maxY = wy + wh;
4745
4746 node = node->Next();
4747 }
4748 SetClientSize(maxX + 5, maxY + 5);
4749 }
4750
4751 void wxWindow::SetValidator(const wxValidator& validator)
4752 {
4753 if ( m_windowValidator )
4754 delete m_windowValidator;
4755 m_windowValidator = validator.Clone();
4756
4757 if ( m_windowValidator )
4758 m_windowValidator->SetWindow(this) ;
4759 }
4760
4761 // Find a window by id or name
4762 wxWindow *wxWindow::FindWindow(const long id)
4763 {
4764 if ( GetId() == id)
4765 return this;
4766
4767 wxNode *node = GetChildren()->First();
4768 while ( node )
4769 {
4770 wxWindow *child = (wxWindow *)node->Data();
4771 wxWindow *found = child->FindWindow(id);
4772 if ( found )
4773 return found;
4774 node = node->Next();
4775 }
4776 return NULL;
4777 }
4778
4779 wxWindow *wxWindow::FindWindow(const wxString& name)
4780 {
4781 if ( GetName() == name)
4782 return this;
4783
4784 wxNode *node = GetChildren()->First();
4785 while ( node )
4786 {
4787 wxWindow *child = (wxWindow *)node->Data();
4788 wxWindow *found = child->FindWindow(name);
4789 if ( found )
4790 return found;
4791 node = node->Next();
4792 }
4793 return NULL;
4794 }
4795
4796 /* TODO
4797 // Default input behaviour for a scrolling canvas should be to scroll
4798 // according to the cursor keys pressed
4799 void wxWindow::OnChar(wxKeyEvent& event)
4800 {
4801 int x_page = 0;
4802 int y_page = 0;
4803 int start_x = 0;
4804 int start_y = 0;
4805 // Bugfix Begin
4806 int v_width = 0;
4807 int v_height = 0;
4808 int y_pages = 0;
4809 // Bugfix End
4810
4811 GetScrollUnitsPerPage(&x_page, &y_page);
4812 // Bugfix Begin
4813 GetVirtualSize(&v_width,&v_height);
4814 // Bugfix End
4815 ViewStart(&start_x, &start_y);
4816 // Bugfix begin
4817 if (vert_units)
4818 y_pages = (int)(v_height/vert_units) - y_page;
4819
4820 #ifdef __WINDOWS__
4821 int y = 0;
4822 #else
4823 int y = y_page-1;
4824 #endif
4825 // Bugfix End
4826 switch (event.keyCode)
4827 {
4828 case WXK_PRIOR:
4829 {
4830 // BugFix Begin
4831 if (y_page > 0)
4832 {
4833 if (start_y - y_page > 0)
4834 Scroll(start_x, start_y - y_page);
4835 else
4836 Scroll(start_x, 0);
4837 }
4838 // Bugfix End
4839 break;
4840 }
4841 case WXK_NEXT:
4842 {
4843 // Bugfix Begin
4844 if ((y_page > 0) && (start_y <= y_pages-y-1))
4845 {
4846 if (y_pages + y < start_y + y_page)
4847 Scroll(start_x, y_pages + y);
4848 else
4849 Scroll(start_x, start_y + y_page);
4850 }
4851 // Bugfix End
4852 break;
4853 }
4854 case WXK_UP:
4855 {
4856 if ((y_page > 0) && (start_y >= 1))
4857 Scroll(start_x, start_y - 1);
4858 break;
4859 }
4860 case WXK_DOWN:
4861 {
4862 // Bugfix Begin
4863 if ((y_page > 0) && (start_y <= y_pages-y-1))
4864 // Bugfix End
4865 {
4866 Scroll(start_x, start_y + 1);
4867 }
4868 break;
4869 }
4870 case WXK_LEFT:
4871 {
4872 if ((x_page > 0) && (start_x >= 1))
4873 Scroll(start_x - 1, start_y);
4874 break;
4875 }
4876 case WXK_RIGHT:
4877 {
4878 if (x_page > 0)
4879 Scroll(start_x + 1, start_y);
4880 break;
4881 }
4882 case WXK_HOME:
4883 {
4884 Scroll(0, 0);
4885 break;
4886 }
4887 // This is new
4888 case WXK_END:
4889 {
4890 Scroll(start_x, y_pages+y);
4891 break;
4892 }
4893 // end
4894 }
4895 }
4896 */
4897
4898 // Setup background and foreground colours correctly
4899 void wxWindow::SetupColours(void)
4900 {
4901 if (GetParent())
4902 SetBackgroundColour(GetParent()->GetBackgroundColour());
4903 }
4904
4905 // Do Update UI processing for child controls
4906
4907 // TODO: should this be implemented for the child window rather
4908 // than the parent? Then you can override it e.g. for wxCheckBox
4909 // to do the Right Thing rather than having to assume a fixed number
4910 // of control classes.
4911
4912 void wxWindow::UpdateWindowUI(void)
4913 {
4914 wxWindowID id = GetId();
4915 if (id > 0)
4916 {
4917 wxUpdateUIEvent event(id);
4918 event.m_eventObject = this;
4919
4920 if (this->GetEventHandler()->ProcessEvent(event))
4921 {
4922 if (event.GetSetEnabled())
4923 this->Enable(event.GetEnabled());
4924
4925 if (event.GetSetText() && this->IsKindOf(CLASSINFO(wxControl)))
4926 ((wxControl*)this)->SetLabel(event.GetText());
4927
4928 if (this->IsKindOf(CLASSINFO(wxCheckBox)))
4929 {
4930 if (event.GetSetChecked())
4931 ((wxCheckBox *) this)->SetValue(event.GetChecked());
4932 }
4933 else if (this->IsKindOf(CLASSINFO(wxRadioButton)))
4934 {
4935 if (event.GetSetChecked())
4936 ((wxRadioButton *) this)->SetValue(event.GetChecked());
4937 }
4938 }
4939 }
4940
4941 }
4942
4943 void wxWindow::OnIdle(wxIdleEvent& event)
4944 {
4945 UpdateWindowUI();
4946 }
4947
4948 // Raise the window to the top of the Z order
4949 void wxWindow::Raise(void)
4950 {
4951 ::BringWindowToTop((HWND) GetHWND());
4952 }
4953
4954 // Lower the window to the bottom of the Z order
4955 void wxWindow::Lower(void)
4956 {
4957 ::SetWindowPos((HWND) GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
4958 }
4959