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