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