]> git.saurik.com Git - wxWidgets.git/blob - src/os2/window.cpp
fixed bug with lower-case colours in wxColourDatabase::AddColour() (patch 1074865)
[wxWidgets.git] / src / os2 / window.cpp
1 // Name: windows.cpp
2 // Purpose: wxWindow
3 // Author: David Webster
4 // Modified by:
5 // Created: 10/12/99
6 // RCS-ID: $Id$
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 //
12 // For compilers that support precompilation, includes "wx.h".
13 //
14 #include "wx/wxprec.h"
15
16 #ifndef WX_PRECOMP
17 #define INCL_DOS
18 #define INCL_PM
19 #include <os2.h>
20 #include "wx/window.h"
21 #include "wx/accel.h"
22 #include "wx/setup.h"
23 #include "wx/menu.h"
24 #include "wx/dc.h"
25 #include "wx/dcclient.h"
26 #include "wx/utils.h"
27 #include "wx/app.h"
28 #include "wx/panel.h"
29 #include "wx/layout.h"
30 #include "wx/checkbox.h"
31 #include "wx/combobox.h"
32 #include "wx/dialog.h"
33 #include "wx/frame.h"
34 #include "wx/listbox.h"
35 #include "wx/button.h"
36 #include "wx/bmpbuttn.h"
37 #include "wx/msgdlg.h"
38 #include "wx/scrolwin.h"
39 #include "wx/radiobox.h"
40 #include "wx/radiobut.h"
41 #include "wx/slider.h"
42 #include "wx/statbox.h"
43 #include "wx/statusbr.h"
44 #include "wx/toolbar.h"
45 #include "wx/settings.h"
46 #include <stdio.h>
47 #endif
48
49 #if wxUSE_OWNER_DRAWN
50 #include "wx/ownerdrw.h"
51 #endif
52
53 #if wxUSE_DRAG_AND_DROP
54 #include "wx/dnd.h"
55 #endif
56
57 #include "wx/menuitem.h"
58 #include "wx/log.h"
59
60 #include "wx/os2/private.h"
61
62 #if wxUSE_TOOLTIPS
63 #include "wx/tooltip.h"
64 #endif
65
66 #if wxUSE_NOTEBOOK
67 #include "wx/notebook.h"
68 #endif
69
70 #if wxUSE_CARET
71 #include "wx/caret.h"
72 #endif // wxUSE_CARET
73
74 #include "wx/intl.h"
75 #include "wx/log.h"
76
77
78 #include "wx/textctrl.h"
79
80 #include <string.h>
81
82 //
83 // Place compiler, OS specific includes here
84 //
85
86 //
87 // Standard macros -- these are for OS/2 PM, but most GUI's have something similar
88 //
89 #ifndef GET_X_LPARAM
90 //
91 // SHORT1FROMMP -- LOWORD
92 //
93 #define GET_X_LPARAM(mp) ((unsigned short)(unsigned long)(mp))
94 //
95 // SHORT2FROMMP -- HIWORD
96 //
97 #define GET_Y_LPARAM(mp) ((unsigned short)(unsigned long)(mp >> 16))
98 #endif // GET_X_LPARAM
99
100 #ifndef CW_USEDEFAULT
101 # define CW_USEDEFAULT ((int)0x80000000)
102 #endif
103
104 #ifndef VK_OEM_1
105 #define VK_OEM_1 0xBA
106 #define VK_OEM_PLUS 0xBB
107 #define VK_OEM_COMMA 0xBC
108 #define VK_OEM_MINUS 0xBD
109 #define VK_OEM_PERIOD 0xBE
110 #define VK_OEM_2 0xBF
111 #define VK_OEM_3 0xC0
112 #define VK_OEM_4 0xDB
113 #define VK_OEM_5 0xDC
114 #define VK_OEM_6 0xDD
115 #define VK_OEM_7 0xDE
116 #endif
117
118 // ---------------------------------------------------------------------------
119 // global variables
120 // ---------------------------------------------------------------------------
121
122 //
123 // The last PM message we got (MT-UNSAFE)
124 //
125 QMSG s_currentMsg;
126
127 #if wxUSE_MENUS_NATIVE
128 wxMenu* wxCurrentPopupMenu = NULL;
129 #endif // wxUSE_MENUS_NATIVE
130
131 // ---------------------------------------------------------------------------
132 // private functions
133 // ---------------------------------------------------------------------------
134
135 //
136 // the window proc for all our windows; most gui's have something similar
137 //
138 MRESULT EXPENTRY wxWndProc( HWND hWnd
139 ,ULONG message
140 ,MPARAM mp1
141 ,MPARAM mp2
142 );
143
144 #ifdef __WXDEBUG__
145 const char *wxGetMessageName(int message);
146 #endif //__WXDEBUG__
147
148 wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin
149 ,short* pnX
150 ,short* pnY
151 );
152 void wxRemoveHandleAssociation(wxWindowOS2* pWin);
153 void wxAssociateWinWithHandle( HWND hWnd
154 ,wxWindowOS2* pWin
155 );
156 wxWindow* wxFindWinFromHandle(WXHWND hWnd);
157
158 //
159 // get the current state of SHIFT/CTRL keys
160 //
161 static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
162 static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
163
164 static wxWindow* gpWinBeingCreated = NULL;
165
166 // ---------------------------------------------------------------------------
167 // event tables
168 // ---------------------------------------------------------------------------
169
170 // in wxUniv-OS/2 this class is abstract because it doesn't have DoPopupMenu()
171 // method
172 #ifdef __WXUNIVERSAL__
173 IMPLEMENT_ABSTRACT_CLASS(wxWindowOS2, wxWindowBase)
174 #else // __WXPM__
175 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
176 #endif // __WXUNIVERSAL__/__WXPM__
177
178 BEGIN_EVENT_TABLE(wxWindowOS2, wxWindowBase)
179 EVT_ERASE_BACKGROUND(wxWindowOS2::OnEraseBackground)
180 EVT_SYS_COLOUR_CHANGED(wxWindowOS2::OnSysColourChanged)
181 EVT_IDLE(wxWindowOS2::OnIdle)
182 EVT_SET_FOCUS(wxWindowOS2::OnSetFocus)
183 END_EVENT_TABLE()
184
185 // ===========================================================================
186 // implementation
187 // ===========================================================================
188
189 // ---------------------------------------------------------------------------
190 // wxWindow utility functions
191 // ---------------------------------------------------------------------------
192
193 //
194 // Find an item given the PM Window id
195 //
196 wxWindow* wxWindowOS2::FindItem(
197 long lId
198 ) const
199 {
200 #if wxUSE_CONTROLS
201 wxControl* pItem = wxDynamicCast(this, wxControl);
202
203 if (pItem)
204 {
205 //
206 // I it we or one of our "internal" children?
207 //
208 if (pItem->GetId() == lId
209 #ifndef __WXUNIVERSAL__
210 || (pItem->GetSubcontrols().Index(lId) != wxNOT_FOUND)
211 #endif
212 )
213 {
214 return pItem;
215 }
216 }
217 #endif // wxUSE_CONTROLS
218
219 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
220
221 while (current)
222 {
223 wxWindow* pChildWin = current->GetData();
224 wxWindow* pWnd = pChildWin->FindItem(lId);
225
226 if (pWnd)
227 return pWnd;
228
229 current = current->GetNext();
230 }
231 return(NULL);
232 } // end of wxWindowOS2::FindItem
233
234 //
235 // Find an item given the PM Window handle
236 //
237 wxWindow* wxWindowOS2::FindItemByHWND(
238 WXHWND hWnd
239 , bool bControlOnly
240 ) const
241 {
242 wxWindowList::compatibility_iterator current = GetChildren().GetFirst();
243
244 while (current)
245 {
246 wxWindow* pParent = current->GetData();
247
248 //
249 // Do a recursive search.
250 //
251 wxWindow* pWnd = pParent->FindItemByHWND(hWnd);
252
253 if (pWnd)
254 return(pWnd);
255
256 if (!bControlOnly
257 #if wxUSE_CONTROLS
258 || pParent->IsKindOf(CLASSINFO(wxControl))
259 #endif // wxUSE_CONTROLS
260 )
261 {
262 wxWindow* pItem = current->GetData();
263
264 if (pItem->GetHWND() == hWnd)
265 return(pItem);
266 else
267 {
268 if (pItem->ContainsHWND(hWnd))
269 return(pItem);
270 }
271 }
272 current = current->GetNext();
273 }
274 return(NULL);
275 } // end of wxWindowOS2::FindItemByHWND
276
277 //
278 // Default command handler
279 //
280 bool wxWindowOS2::OS2Command(
281 WXUINT WXUNUSED(uParam)
282 , WXWORD WXUNUSED(uId)
283 )
284 {
285 return(FALSE);
286 }
287
288 // ----------------------------------------------------------------------------
289 // constructors and such
290 // ----------------------------------------------------------------------------
291
292 void wxWindowOS2::Init()
293 {
294 //
295 // PM specific
296 //
297 m_bWinCaptured = FALSE;
298
299 m_fnOldWndProc = NULL;
300 m_bUseCtl3D = FALSE;
301 m_bMouseInWindow = FALSE;
302 m_bLastKeydownProcessed = FALSE;
303 m_pChildrenDisabled = NULL;
304
305 //
306 // wxWnd
307 //
308 m_hMenu = 0L;
309 m_hWnd = 0L;
310 m_hWndScrollBarHorz = 0L;
311 m_hWndScrollBarVert = 0L;
312
313 memset(&m_vWinSwp, '\0', sizeof (SWP));
314
315 //
316 // Pass WM_GETDLGCODE to DefWindowProc()
317 //
318 m_lDlgCode = 0;
319
320 m_nXThumbSize = 0;
321 m_nYThumbSize = 0;
322 m_bBackgroundTransparent = FALSE;
323
324 //
325 // As all windows are created with WS_VISIBLE style...
326 //
327 m_isShown = TRUE;
328
329 #if wxUSE_MOUSEEVENT_HACK
330 m_lLastMouseX =
331 m_lLastMouseY = -1;
332 m_nLastMouseEvent = -1;
333 #endif // wxUSE_MOUSEEVENT_HACK
334 } // wxWindowOS2::Init
335
336 //
337 // Destructor
338 //
339 wxWindowOS2::~wxWindowOS2()
340 {
341 m_isBeingDeleted = TRUE;
342
343 for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
344 {
345 wxTopLevelWindow* pFrame = wxDynamicCast(pWin, wxTopLevelWindow);
346
347 if (pFrame)
348 {
349 if (pFrame->GetLastFocus() == this)
350 pFrame->SetLastFocus(NULL);
351 }
352 }
353
354 DestroyChildren();
355
356 if (m_hWnd)
357 {
358 if(!::WinDestroyWindow(GetHWND()))
359 wxLogLastError(wxT("DestroyWindow"));
360 //
361 // remove hWnd <-> wxWindow association
362 //
363 wxRemoveHandleAssociation(this);
364 }
365 delete m_pChildrenDisabled;
366 } // end of wxWindowOS2::~wxWindowOS2
367
368 // real construction (Init() must have been called before!)
369 bool wxWindowOS2::Create(
370 wxWindow* pParent
371 , wxWindowID vId
372 , const wxPoint& rPos
373 , const wxSize& rSize
374 , long lStyle
375 , const wxString& rName
376 )
377 {
378 HWND hParent = NULLHANDLE;
379 ULONG ulCreateFlags = 0;
380 WXDWORD dwExStyle = 0;
381
382 wxCHECK_MSG(pParent, FALSE, wxT("can't create wxWindow without parent"));
383
384 #if wxUSE_STATBOX
385 //
386 // wxGTK doesn't allow to create controls with static box as the parent so
387 // this will result in a crash when the program is ported to wxGTK - warn
388 // about it
389 //
390 // the correct solution is to create the controls as siblings of the
391 // static box
392 //
393 wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
394 _T("wxStaticBox can't be used as a window parent!") );
395 #endif // wxUSE_STATBOX
396
397 if ( !CreateBase( pParent
398 ,vId
399 ,rPos
400 ,rSize
401 ,lStyle
402 ,wxDefaultValidator
403 ,rName
404 ))
405 return(FALSE);
406
407 if (pParent)
408 {
409 pParent->AddChild(this);
410 hParent = GetWinHwnd(pParent);
411
412 if ( pParent->IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
413 pParent->IsKindOf(CLASSINFO(wxScrolledWindow))
414 )
415 ulCreateFlags |= WS_CLIPSIBLINGS;
416 }
417
418 //
419 // Most wxSTYLES are really PM Class specific styles and will be
420 // set in those class create procs. PM's basic windows styles are
421 // very limited.
422 //
423 ulCreateFlags |= OS2GetCreateWindowFlags(&dwExStyle);
424
425
426 #ifdef __WXUNIVERSAL__
427 // no 3d effects, we draw them ourselves
428 WXDWORD exStyle = 0;
429 #endif // !wxUniversal
430 if (lStyle & wxPOPUP_WINDOW)
431 {
432 ulCreateFlags &= ~WS_VISIBLE;
433 m_isShown = FALSE;
434 }
435 else
436 {
437 ulCreateFlags |= WS_VISIBLE;
438 }
439
440 //
441 // Generic OS/2 Windows have no Control Data but other classes
442 // that call OS2Create may have some.
443 //
444 return(OS2Create( (PSZ)wxCanvasClassName
445 ,rName.c_str()
446 ,ulCreateFlags
447 ,rPos
448 ,rSize
449 ,NULL // Control Data
450 ,dwExStyle
451 ,TRUE // Child
452 ));
453 } // end of wxWindowOS2::Create
454
455 // ---------------------------------------------------------------------------
456 // basic operations
457 // ---------------------------------------------------------------------------
458
459 void wxWindowOS2::SetFocus()
460 {
461 HWND hWnd = GetHwnd();
462 wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
463
464 if (hWnd)
465 ::WinSetFocus(HWND_DESKTOP, hWnd);
466 } // end of wxWindowOS2::SetFocus
467
468 void wxWindowOS2::SetFocusFromKbd()
469 {
470 //
471 // Nothing else to do under OS/2
472 //
473 wxWindowBase::SetFocusFromKbd();
474 } // end of wxWindowOS2::SetFocus
475
476 wxWindow* wxWindowBase::DoFindFocus()
477 {
478 HWND hWnd = ::WinQueryFocus(HWND_DESKTOP);
479
480 if (hWnd)
481 {
482 return wxFindWinFromHandle((WXHWND)hWnd);
483 }
484 return NULL;
485 } // wxWindowBase::DoFindFocus
486
487 bool wxWindowOS2::Enable(
488 bool bEnable
489 )
490 {
491 if (!wxWindowBase::Enable(bEnable))
492 return(FALSE);
493
494 HWND hWnd = GetHwnd();
495
496 if ( hWnd )
497 ::WinEnableWindow(hWnd, (BOOL)bEnable);
498
499 //
500 // The logic below doesn't apply to the top level windows -- otherwise
501 // showing a modal dialog would result in total greying out (and ungreying
502 // out later) of everything which would be really ugly
503 //
504 if (IsTopLevel())
505 return TRUE;
506
507 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
508
509 while (node)
510 {
511 wxWindow* pChild = node->GetData();
512
513 if (bEnable)
514 {
515 //
516 // Enable the child back unless it had been disabled before us
517 //
518 if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild))
519 pChild->Enable();
520 }
521 else // we're being disabled
522 {
523 if (pChild->IsEnabled())
524 {
525 //
526 // Disable it as children shouldn't stay enabled while the
527 // parent is not
528 //
529 pChild->Disable();
530 }
531 else // child already disabled, remember it
532 {
533 //
534 // Have we created the list of disabled children already?
535 //
536 if (!m_pChildrenDisabled)
537 m_pChildrenDisabled = new wxWindowList;
538 m_pChildrenDisabled->Append(pChild);
539 }
540 }
541 node = node->GetNext();
542 }
543 if (bEnable && m_pChildrenDisabled)
544 {
545 //
546 // We don't need this list any more, don't keep unused memory
547 //
548 delete m_pChildrenDisabled;
549 m_pChildrenDisabled = NULL;
550 }
551 return TRUE;
552 } // end of wxWindowOS2::Enable
553
554 bool wxWindowOS2::Show(
555 bool bShow
556 )
557 {
558 if (!wxWindowBase::Show(bShow))
559 return(FALSE);
560
561 HWND hWnd = GetHwnd();
562
563 ::WinShowWindow(hWnd, bShow);
564
565 if (bShow)
566 {
567 ::WinSetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE | SWP_ZORDER);
568 }
569 return TRUE;
570 } // end of wxWindowOS2::Show
571
572 void wxWindowOS2::Raise()
573 {
574 ::WinSetWindowPos(GetHwnd(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER | SWP_ACTIVATE);
575 } // end of wxWindowOS2::Raise
576
577 void wxWindowOS2::Lower()
578 {
579 ::WinSetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_ZORDER | SWP_DEACTIVATE);
580 } // end of wxWindowOS2::Lower
581
582 void wxWindowOS2::SetTitle(
583 const wxString& rTitle
584 )
585 {
586 ::WinSetWindowText(GetHwnd(), rTitle.c_str());
587 } // end of wxWindowOS2::SetTitle
588
589 wxString wxWindowOS2::GetTitle() const
590 {
591 return wxGetWindowText(GetHWND());
592 } // end of wxWindowOS2::GetTitle
593
594 void wxWindowOS2::DoCaptureMouse()
595 {
596 HWND hWnd = GetHwnd();
597
598 if (hWnd && !m_bWinCaptured)
599 {
600 ::WinSetCapture(HWND_DESKTOP, hWnd);
601 m_bWinCaptured = TRUE;
602 }
603 } // end of wxWindowOS2::GetTitle
604
605 void wxWindowOS2::DoReleaseMouse()
606 {
607 if (m_bWinCaptured)
608 {
609 ::WinSetCapture(HWND_DESKTOP, NULLHANDLE);
610 m_bWinCaptured = FALSE;
611 }
612 } // end of wxWindowOS2::ReleaseMouse
613
614 /* static */ wxWindow* wxWindowBase::GetCapture()
615 {
616 HWND hwnd = ::WinQueryCapture(HWND_DESKTOP);
617 return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
618 } // end of wxWindowBase::GetCapture
619
620 bool wxWindowOS2::SetFont(
621 const wxFont& rFont
622 )
623 {
624 if (!wxWindowBase::SetFont(rFont))
625 {
626 // nothing to do
627 return(FALSE);
628 }
629
630 HWND hWnd = GetHwnd();
631
632 wxOS2SetFont( hWnd
633 ,rFont
634 );
635 return(TRUE);
636 } // end of wxWindowOS2::SetFont
637
638 bool wxWindowOS2::SetCursor(
639 const wxCursor& rCursor
640 ) // check if base implementation is OK
641 {
642 if ( !wxWindowBase::SetCursor(rCursor))
643 {
644 // no change
645 return FALSE;
646 }
647
648 if ( m_cursor.Ok() ) {
649 HWND hWnd = GetHwnd();
650 POINTL vPoint;
651 RECTL vRect;
652
653 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
654 ::WinQueryWindowRect(hWnd, &vRect);
655
656 if (::WinPtInRect(vHabmain, &vRect, &vPoint) && !wxIsBusy())
657 {
658 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)m_cursor.GetHCURSOR());
659 }
660 }
661 return TRUE;
662 } // end of wxWindowOS2::SetCursor
663
664 void wxWindowOS2::WarpPointer(
665 int nXPos
666 , int nYPos
667 )
668 {
669 int nX = nXPos;
670 int nY = nYPos;
671 RECTL vRect;
672
673 ::WinQueryWindowRect(GetHwnd(), &vRect);
674 nX += vRect.xLeft;
675 nY += vRect.yBottom;
676
677 ::WinSetPointerPos(HWND_DESKTOP, (LONG)nX, (LONG)(nY));
678 } // end of wxWindowOS2::WarpPointer
679
680
681 // ---------------------------------------------------------------------------
682 // scrolling stuff
683 // ---------------------------------------------------------------------------
684
685 int wxWindowOS2::GetScrollPos(
686 int nOrient
687 ) const
688 {
689 if (nOrient == wxHORIZONTAL)
690 return((int)::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
691 else
692 return((int)::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYPOS, (MPARAM)NULL, (MPARAM)NULL));
693 } // end of wxWindowOS2::GetScrollPos
694
695 int wxWindowOS2::GetScrollRange(
696 int nOrient
697 ) const
698 {
699 MRESULT mr;
700
701 if (nOrient == wxHORIZONTAL)
702 mr = ::WinSendMsg(m_hWndScrollBarHorz, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
703 else
704 mr = ::WinSendMsg(m_hWndScrollBarVert, SBM_QUERYRANGE, (MPARAM)NULL, (MPARAM)NULL);
705 return((int)SHORT2FROMMR(mr));
706 } // end of wxWindowOS2::GetScrollRange
707
708 int wxWindowOS2::GetScrollThumb(
709 int nOrient
710 ) const
711 {
712 if (nOrient == wxHORIZONTAL )
713 return m_nXThumbSize;
714 else
715 return m_nYThumbSize;
716 } // end of wxWindowOS2::GetScrollThumb
717
718 void wxWindowOS2::SetScrollPos(
719 int nOrient
720 , int nPos
721 , bool WXUNUSED(bRefresh)
722 )
723 {
724 if (nOrient == wxHORIZONTAL )
725 ::WinSendMsg(m_hWndScrollBarHorz, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
726 else
727 ::WinSendMsg(m_hWndScrollBarVert, SBM_SETPOS, (MPARAM)nPos, (MPARAM)NULL);
728 } // end of wxWindowOS2::SetScrollPos
729
730 void wxWindowOS2::SetScrollbar(
731 int nOrient
732 , int nPos
733 , int nThumbVisible
734 , int nRange
735 , bool WXUNUSED(bRefresh)
736 )
737 {
738 HWND hWnd = GetHwnd();
739 int nOldRange = nRange - nThumbVisible;
740 int nRange1 = nOldRange;
741 int nPageSize = nThumbVisible;
742
743 SBCDATA vInfo;
744 ULONG ulStyle = WS_VISIBLE | WS_SYNCPAINT;
745 SWP vSwp;
746 SWP vSwpOwner;
747 HWND hWndParent;
748 HWND hWndClient;
749 wxWindow* pParent = GetParent();
750
751 if (pParent && pParent->IsKindOf(CLASSINFO(wxFrame)))
752 {
753 wxFrame* pFrame;
754
755 pFrame = wxDynamicCast(pParent, wxFrame);
756 hWndParent = pFrame->GetFrame();
757 hWndClient = GetHwndOf(pParent);
758 }
759 else
760 {
761 if (pParent)
762 hWndParent = GetHwndOf(pParent);
763 else
764 hWndParent = GetHwnd();
765 hWndClient = hWndParent;
766 }
767 ::WinQueryWindowPos(hWndClient, &vSwp);
768 ::WinQueryWindowPos(hWnd, &vSwpOwner);
769
770 if (nPageSize > 1 && nRange > 0)
771 {
772 nRange1 += (nPageSize - 1);
773 }
774
775 vInfo.cb = sizeof(SBCDATA);
776 vInfo.posFirst = 0;
777 vInfo.posLast = (SHORT)nRange1;
778 vInfo.posThumb = nPos;
779
780 if (nOrient == wxHORIZONTAL )
781 {
782 ulStyle |= SBS_HORZ;
783 if (m_hWndScrollBarHorz == 0L)
784 {
785 //
786 // Since the scrollbars are usually created before the owner is
787 // sized either via an OnSize event directly or via sizers or
788 // layout constraints, we will initially just use the coords of
789 // the parent window (this is usually a frame client window). But
790 // the bars themselves, are children of the parent frame (i.e
791 // siblings of the frame client. The owner, however is the actual
792 // window being scrolled (or at least the one responsible for
793 // handling the scroll events). The owner will be resized later,
794 // as it is usually a child of a top level window, and when that
795 // is done its scrollbars will be resized and repositioned as well.
796 //
797 m_hWndScrollBarHorz = ::WinCreateWindow( hWndParent
798 ,WC_SCROLLBAR
799 ,(PSZ)NULL
800 ,ulStyle
801 ,vSwp.x
802 ,vSwp.y
803 ,vSwp.cx - 20
804 ,20
805 ,hWnd
806 ,HWND_TOP
807 ,60000
808 ,&vInfo
809 ,NULL
810 );
811 }
812 else
813 {
814 //
815 // The owner (the scrolled window) is a child of the Frame's
816 // client window, usually. The scrollbars are children of the
817 // frame, itself, and thus are positioned relative to the frame's
818 // origin, not the frame's client window origin.
819 // The starting x position is the same as the starting x position
820 // of the owner, but in terms of the parent frame.
821 // The starting y position is 20 pels below the origin of the
822 // owner in terms of the parent frame.
823 // The horz bar is the same width as the owner and 20 pels high.
824 //
825 if (nRange1 >= nThumbVisible)
826 {
827 ::WinSetWindowPos( m_hWndScrollBarHorz
828 ,HWND_TOP
829 ,vSwp.x + vSwpOwner.x
830 ,(vSwp.y + vSwpOwner.y) - 20
831 ,vSwpOwner.cx
832 ,20
833 ,SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER
834 );
835 ::WinSendMsg( m_hWndScrollBarHorz
836 ,SBM_SETSCROLLBAR
837 ,(MPARAM)nPos
838 ,MPFROM2SHORT(0, (SHORT)nRange1)
839 );
840 ::WinSendMsg( m_hWndScrollBarHorz
841 ,SBM_SETTHUMBSIZE
842 ,MPFROM2SHORT( (SHORT)nThumbVisible
843 ,(SHORT)nRange1
844 )
845 ,(MPARAM)0
846 );
847 }
848 else
849 ::WinShowWindow(m_hWndScrollBarHorz, FALSE);
850 }
851 }
852 else
853 {
854 ulStyle |= SBS_VERT;
855 if (m_hWndScrollBarVert == 0L)
856 {
857 //
858 // Since the scrollbars are usually created before the owner is
859 // sized either via an OnSize event directly or via sizers or
860 // layout constraints, we will initially just use the coords of
861 // the parent window (this is usually a frame client window). But
862 // the bars themselves, are children of the parent frame (i.e
863 // siblings of the frame client. The owner, however is the actual
864 // window being scrolled (or at least the one responsible for
865 // handling the scroll events). The owner will be resized later,
866 // as it is usually a child of a top level window, and when that
867 // is done its scrollbars will be resized and repositioned as well.
868 //
869 m_hWndScrollBarVert = ::WinCreateWindow( hWndParent
870 ,WC_SCROLLBAR
871 ,(PSZ)NULL
872 ,ulStyle
873 ,vSwp.x + vSwp.cx - 20
874 ,vSwp.y + 20
875 ,20
876 ,vSwp.cy - 20
877 ,hWnd
878 ,HWND_TOP
879 ,60001
880 ,&vInfo
881 ,NULL
882 );
883 }
884 else
885 {
886 //
887 // The owner (the scrolled window) is a child of the Frame's
888 // client window, usually. The scrollbars are children of the
889 // frame, itself and thus are positioned relative to the frame's
890 // origin, not the frame's client window's origin.
891 // Thus, the x position will be frame client's x (usually a few
892 // pels inside the parent frame, plus the width of the owner.
893 // Since we may be using sizers or layout constraints for multiple
894 // child scrolled windows, the y position will be the frame client's
895 // y pos plus the scrolled windows y position, yielding the y
896 // position of the scrollbar relative to the parent frame (the vert
897 // scrollbar is on the right and starts at the bottom of the
898 // owner window).
899 // It is 20 pels wide and the same height as the owner.
900 //
901 if (nRange1 >= nThumbVisible)
902 {
903 ::WinSetWindowPos( m_hWndScrollBarVert
904 ,HWND_TOP
905 ,vSwp.x + vSwpOwner.x + vSwpOwner.cx
906 ,vSwp.y + vSwpOwner.y
907 ,20
908 ,vSwpOwner.cy
909 ,SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW
910 );
911 ::WinSendMsg( m_hWndScrollBarVert
912 ,SBM_SETSCROLLBAR
913 ,(MPARAM)nPos
914 ,MPFROM2SHORT(0, (SHORT)nRange1)
915 );
916 ::WinSendMsg( m_hWndScrollBarVert
917 ,SBM_SETTHUMBSIZE
918 ,MPFROM2SHORT( (SHORT)nThumbVisible
919 ,(SHORT)nRange1
920 )
921 ,(MPARAM)0
922 );
923 }
924 else
925 ::WinShowWindow(m_hWndScrollBarVert, FALSE);
926 }
927 m_nYThumbSize = nThumbVisible;
928 }
929 } // end of wxWindowOS2::SetScrollbar
930
931 void wxWindowOS2::ScrollWindow(
932 int nDx
933 , int nDy
934 , const wxRect* pRect
935 )
936 {
937 RECTL vRect;
938
939 ::WinQueryWindowRect(GetHwnd(), &vRect);
940 int height = vRect.yTop;
941 if (pRect)
942 {
943 vRect.xLeft = pRect->x;
944 vRect.yTop = height - pRect->y;
945 vRect.xRight = pRect->x + pRect->width;
946 vRect.yBottom = vRect.yTop - pRect->height;
947 }
948 nDy *= -1; // flip the sign of Dy as OS/2 is opposite Windows.
949 ::WinScrollWindow( GetHwnd()
950 ,(LONG)nDx
951 ,(LONG)nDy
952 ,&vRect
953 ,&vRect
954 ,NULL
955 ,NULL
956 ,SW_SCROLLCHILDREN | SW_INVALIDATERGN
957 );
958 } // end of wxWindowOS2::ScrollWindow
959
960 // ---------------------------------------------------------------------------
961 // subclassing
962 // ---------------------------------------------------------------------------
963
964 void wxWindowOS2::SubclassWin(
965 WXHWND hWnd
966 )
967 {
968 HWND hwnd = (HWND)hWnd;
969
970 wxCHECK_RET(::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in SubclassWin") );
971 wxAssociateWinWithHandle( hWnd
972 ,(wxWindow*)this
973 );
974 if (!wxCheckWindowWndProc( hWnd
975 ,(WXFARPROC)wxWndProc
976 ))
977 {
978 m_fnOldWndProc = (WXFARPROC) ::WinSubclassWindow(hwnd, (PFNWP)wxWndProc);
979 }
980 else
981 {
982 m_fnOldWndProc = (WXFARPROC)NULL;
983 }
984 } // end of wxWindowOS2::SubclassWin
985
986 void wxWindowOS2::UnsubclassWin()
987 {
988 //
989 // Restore old Window proc
990 //
991 HWND hwnd = GetHWND();
992
993 if (m_hWnd)
994 {
995 wxCHECK_RET( ::WinIsWindow(vHabmain, hwnd), wxT("invalid HWND in UnsubclassWin") );
996
997 PFNWP fnProc = (PFNWP)::WinQueryWindowPtr(hwnd, QWP_PFNWP);
998
999 if ( (m_fnOldWndProc != 0) && (fnProc != (PFNWP) m_fnOldWndProc))
1000 {
1001 WinSubclassWindow(hwnd, (PFNWP)m_fnOldWndProc);
1002 m_fnOldWndProc = 0;
1003 }
1004 }
1005 } // end of wxWindowOS2::UnsubclassWin
1006
1007 bool wxCheckWindowWndProc(
1008 WXHWND hWnd
1009 , WXFARPROC fnWndProc
1010 )
1011 {
1012 static char zBuffer[512];
1013 CLASSINFO vCls;
1014
1015 ::WinQueryClassName((HWND)hWnd, (LONG)512, (PCH)zBuffer);
1016 ::WinQueryClassInfo(wxGetInstance(), (PSZ)zBuffer, &vCls);
1017 return(fnWndProc == (WXFARPROC)vCls.pfnWindowProc);
1018 } // end of WinGuiBase_CheckWindowWndProc
1019
1020 void wxWindowOS2::SetWindowStyleFlag(
1021 long lFlags
1022 )
1023 {
1024 long lFlagsOld = GetWindowStyleFlag();
1025
1026 if (lFlags == lFlagsOld)
1027 return;
1028
1029 //
1030 // Update the internal variable
1031 //
1032 wxWindowBase::SetWindowStyleFlag(lFlags);
1033
1034 //
1035 // Now update the Windows style as well if needed - and if the window had
1036 // been already created
1037 //
1038 if (!GetHwnd())
1039 return;
1040
1041 WXDWORD dwExstyle;
1042 WXDWORD dwExstyleOld;
1043 long lStyle = OS2GetStyle( lFlags
1044 ,&dwExstyle
1045 );
1046 long lStyleOld = OS2GetStyle( lFlagsOld
1047 ,&dwExstyleOld
1048 );
1049
1050 if (lStyle != lStyleOld)
1051 {
1052 //
1053 // Some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
1054 // this function so instead of simply setting the style to the new
1055 // value we clear the bits which were set in styleOld but are set in
1056 // the new one and set the ones which were not set before
1057 //
1058 long lStyleReal = ::WinQueryWindowULong(GetHwnd(), QWL_STYLE);
1059
1060 lStyleReal &= ~lStyleOld;
1061 lStyleReal |= lStyle;
1062
1063 ::WinSetWindowULong(GetHwnd(), QWL_STYLE, lStyleReal);
1064 }
1065 } // end of wxWindowOS2::SetWindowStyleFlag
1066
1067 WXDWORD wxWindowOS2::OS2GetStyle(
1068 long lFlags
1069 , WXDWORD* pdwExstyle
1070 ) const
1071 {
1072 WXDWORD dwStyle = 0L;
1073
1074 if (lFlags & wxCLIP_CHILDREN )
1075 dwStyle |= WS_CLIPCHILDREN;
1076
1077 if (lFlags & wxCLIP_SIBLINGS )
1078 dwStyle |= WS_CLIPSIBLINGS;
1079
1080 return dwStyle;
1081 } // end of wxWindowMSW::MSWGetStyle
1082
1083 //
1084 // Make a Windows extended style from the given wxWidgets window style
1085 //
1086 WXDWORD wxWindowOS2::MakeExtendedStyle(
1087 long lStyle
1088 , bool bEliminateBorders
1089 )
1090 {
1091 //
1092 // Simply fill out with wxWindow extended styles. We'll conjure
1093 // something up in OS2Create and all window redrawing pieces later
1094 //
1095 WXDWORD dwStyle = 0;
1096
1097 if (lStyle & wxTRANSPARENT_WINDOW )
1098 dwStyle |= wxTRANSPARENT_WINDOW;
1099
1100 if (!bEliminateBorders)
1101 {
1102 if (lStyle & wxSUNKEN_BORDER)
1103 dwStyle |= wxSUNKEN_BORDER;
1104 if (lStyle & wxDOUBLE_BORDER)
1105 dwStyle |= wxDOUBLE_BORDER;
1106 if (lStyle & wxRAISED_BORDER )
1107 dwStyle |= wxRAISED_BORDER;
1108 if (lStyle & wxSTATIC_BORDER)
1109 dwStyle |= wxSTATIC_BORDER;
1110 }
1111 return dwStyle;
1112 } // end of wxWindowOS2::MakeExtendedStyle
1113
1114 //
1115 // Setup background and foreground colours correctly
1116 //
1117 void wxWindowOS2::SetupColours()
1118 {
1119 if ( GetParent() )
1120 SetBackgroundColour(GetParent()->GetBackgroundColour());
1121 } // end of wxWindowOS2::SetupColours
1122
1123 void wxWindowOS2::OnIdle(
1124 wxIdleEvent& WXUNUSED(rEvent)
1125 )
1126 {
1127 //
1128 // Check if we need to send a LEAVE event
1129 //
1130 if (m_bMouseInWindow)
1131 {
1132 POINTL vPoint;
1133
1134 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
1135 if (::WinWindowFromPoint(HWND_DESKTOP, &vPoint, FALSE) != (HWND)GetHwnd())
1136 {
1137 //
1138 // Generate a LEAVE event
1139 //
1140 m_bMouseInWindow = FALSE;
1141
1142 //
1143 // Unfortunately the mouse button and keyboard state may have changed
1144 // by the time the OnIdle function is called, so 'state' may be
1145 // meaningless.
1146 //
1147 int nState = 0;
1148
1149 if (IsShiftDown())
1150 nState |= KC_SHIFT;
1151 if (IsCtrlDown())
1152 nState |= KC_CTRL;
1153
1154 wxMouseEvent rEvent(wxEVT_LEAVE_WINDOW);
1155
1156 InitMouseEvent( rEvent
1157 ,vPoint.x
1158 ,vPoint.y
1159 ,nState
1160 );
1161 (void)GetEventHandler()->ProcessEvent(rEvent);
1162 }
1163 }
1164 if (wxUpdateUIEvent::CanUpdate(this))
1165 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
1166 } // end of wxWindowOS2::OnIdle
1167
1168 //
1169 // Set this window to be the child of 'parent'.
1170 //
1171 bool wxWindowOS2::Reparent(
1172 wxWindow* pParent
1173 )
1174 {
1175 if (!wxWindowBase::Reparent(pParent))
1176 return FALSE;
1177
1178 HWND hWndChild = GetHwnd();
1179 HWND hWndParent = GetParent() ? GetWinHwnd(GetParent()) : (HWND)0;
1180
1181 ::WinSetParent(hWndChild, hWndParent, TRUE);
1182 return TRUE;
1183 } // end of wxWindowOS2::Reparent
1184
1185 void wxWindowOS2::Update()
1186 {
1187 ::WinUpdateWindow(GetHwnd());
1188 } // end of wxWindowOS2::Update
1189
1190 void wxWindowOS2::Freeze()
1191 {
1192 ::WinSendMsg(GetHwnd(), WM_VRNDISABLED, (MPARAM)0, (MPARAM)0);
1193 } // end of wxWindowOS2::Freeze
1194
1195 void wxWindowOS2::Thaw()
1196 {
1197 ::WinSendMsg(GetHwnd(), WM_VRNENABLED, (MPARAM)TRUE, (MPARAM)0);
1198
1199 //
1200 // We need to refresh everything or otherwise he invalidated area is not
1201 // repainted.
1202 //
1203 Refresh();
1204 } // end of wxWindowOS2::Thaw
1205
1206 void wxWindowOS2::Refresh(
1207 bool bEraseBack
1208 , const wxRect* pRect
1209 )
1210 {
1211 HWND hWnd = GetHwnd();
1212
1213 if (hWnd)
1214 {
1215 if (pRect)
1216 {
1217 RECTL vOs2Rect;
1218 int height;
1219
1220 ::WinQueryWindowRect(GetHwnd(), &vOs2Rect);
1221 height = vOs2Rect.yTop;
1222 vOs2Rect.xLeft = pRect->x;
1223 vOs2Rect.yTop = height - pRect->y;
1224 vOs2Rect.xRight = pRect->x + pRect->width;
1225 vOs2Rect.yBottom = vOs2Rect.yTop - pRect->height;
1226
1227 ::WinInvalidateRect(hWnd, &vOs2Rect, bEraseBack);
1228 }
1229 else
1230 ::WinInvalidateRect(hWnd, NULL, bEraseBack);
1231 if (m_hWndScrollBarHorz != NULLHANDLE)
1232 ::WinInvalidateRect(m_hWndScrollBarHorz, NULL, TRUE);
1233 if (m_hWndScrollBarVert != NULLHANDLE)
1234 ::WinInvalidateRect(m_hWndScrollBarVert, NULL, TRUE);
1235 }
1236 } // end of wxWindowOS2::Refresh
1237
1238 // ---------------------------------------------------------------------------
1239 // drag and drop
1240 // ---------------------------------------------------------------------------
1241
1242 #if wxUSE_DRAG_AND_DROP
1243 void wxWindowOS2::SetDropTarget(
1244 wxDropTarget* pDropTarget
1245 )
1246 {
1247 m_dropTarget = pDropTarget;
1248 } // end of wxWindowOS2::SetDropTarget
1249 #endif
1250
1251 //
1252 // old style file-manager drag&drop support: we retain the old-style
1253 // DragAcceptFiles in parallel with SetDropTarget.
1254 //
1255 void wxWindowOS2::DragAcceptFiles(
1256 bool bAccept
1257 )
1258 {
1259 HWND hWnd = GetHwnd();
1260
1261 if (hWnd && bAccept)
1262 ::DrgAcceptDroppedFiles(hWnd, NULL, NULL, DO_COPY, 0L);
1263 } // end of wxWindowOS2::DragAcceptFiles
1264
1265 // ----------------------------------------------------------------------------
1266 // tooltips
1267 // ----------------------------------------------------------------------------
1268
1269 #if wxUSE_TOOLTIPS
1270
1271 void wxWindowOS2::DoSetToolTip(
1272 wxToolTip* pTooltip
1273 )
1274 {
1275 wxWindowBase::DoSetToolTip(pTooltip);
1276
1277 if (m_tooltip)
1278 m_tooltip->SetWindow(this);
1279 } // end of wxWindowOS2::DoSetToolTip
1280
1281 #endif // wxUSE_TOOLTIPS
1282
1283 // ---------------------------------------------------------------------------
1284 // moving and resizing
1285 // ---------------------------------------------------------------------------
1286
1287 // Get total size
1288 void wxWindowOS2::DoGetSize(
1289 int* pWidth
1290 , int* pHeight
1291 ) const
1292 {
1293 HWND hWnd;
1294 RECTL vRect;
1295
1296 if (IsKindOf(CLASSINFO(wxFrame)))
1297 {
1298 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1299 hWnd = pFrame->GetFrame();
1300 }
1301 else
1302 hWnd = GetHwnd();
1303
1304 ::WinQueryWindowRect(hWnd, &vRect);
1305
1306 if (pWidth)
1307 *pWidth = vRect.xRight - vRect.xLeft;
1308 if (pHeight )
1309 // OS/2 PM is backwards from windows
1310 *pHeight = vRect.yTop - vRect.yBottom;
1311 } // end of wxWindowOS2::DoGetSize
1312
1313 void wxWindowOS2::DoGetPosition(
1314 int* pX
1315 , int* pY
1316 ) const
1317 {
1318 HWND hWnd = GetHwnd();
1319 SWP vSwp;
1320 POINTL vPoint;
1321 wxWindow* pParent = GetParent();
1322
1323 //
1324 // It would seem that WinQueryWindowRect would be the correlary to
1325 // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
1326 // origin position in screen coordinates, WinQueryWindowRect returns it
1327 // relative to itself, i.e. (0,0). To get the same under PM we must
1328 // us WinQueryWindowPos. This call, unlike the WIN32 call, however,
1329 // returns a position relative to it's parent, so no parent adujstments
1330 // are needed under OS/2. Also, windows should be created using
1331 // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
1332 // reflect that.
1333 //
1334 ::WinQueryWindowPos(hWnd, &vSwp);
1335
1336 vPoint.x = vSwp.x;
1337 vPoint.y = vSwp.y;
1338
1339 //
1340 // We may be faking the client origin. So a window that's really at (0,
1341 // 30) may appear (to wxWin apps) to be at (0, 0).
1342 //
1343 if (pParent)
1344 {
1345 wxPoint vPt(pParent->GetClientAreaOrigin());
1346
1347 vPoint.x -= vPt.x;
1348 vPoint.y -= vPt.y;
1349 }
1350
1351 if (pX)
1352 *pX = vPoint.x;
1353 if (pY)
1354 *pY = vPoint.y;
1355 } // end of wxWindowOS2::DoGetPosition
1356
1357 void wxWindowOS2::DoScreenToClient(
1358 int* pX
1359 , int* pY
1360 ) const
1361 {
1362 HWND hWnd = GetHwnd();
1363 SWP vSwp;
1364
1365 ::WinQueryWindowPos(hWnd, &vSwp);
1366
1367 if (pX)
1368 *pX += vSwp.x;
1369 if (pY)
1370 *pY += vSwp.y;
1371 } // end of wxWindowOS2::DoScreenToClient
1372
1373 void wxWindowOS2::DoClientToScreen(
1374 int* pX
1375 , int* pY
1376 ) const
1377 {
1378 HWND hWnd = GetHwnd();
1379 SWP vSwp;
1380
1381 ::WinQueryWindowPos(hWnd, &vSwp);
1382
1383 if (pX)
1384 *pX += vSwp.x;
1385 if (pY)
1386 *pY += vSwp.y;
1387 } // end of wxWindowOS2::DoClientToScreen
1388
1389 //
1390 // Get size *available for subwindows* i.e. excluding menu bar etc.
1391 // Must be a frame type window
1392 //
1393 void wxWindowOS2::DoGetClientSize(
1394 int* pWidth
1395 , int* pHeight
1396 ) const
1397 {
1398 HWND hWnd = GetHwnd();
1399 RECTL vRect;
1400
1401 ::WinQueryWindowRect(hWnd, &vRect);
1402 if (IsKindOf(CLASSINFO(wxDialog)))
1403 {
1404 RECTL vTitle;
1405 HWND hWndTitle;
1406 //
1407 // For a Dialog we have to explicitly request the client portion.
1408 // For a Frame the hWnd IS the client window
1409 //
1410 hWndTitle = ::WinWindowFromID(hWnd, FID_TITLEBAR);
1411 if (::WinQueryWindowRect(hWndTitle, &vTitle))
1412 {
1413 if (vTitle.yTop - vTitle.yBottom == 0)
1414 {
1415 //
1416 // Dialog has not been created yet, use a default
1417 //
1418 vTitle.yTop = 20;
1419 }
1420 vRect.yTop -= (vTitle.yTop - vTitle.yBottom);
1421 }
1422
1423 ULONG uStyle = ::WinQueryWindowULong(hWnd, QWL_STYLE);
1424
1425 //
1426 // Deal with borders
1427 //
1428 if (uStyle & FCF_DLGBORDER)
1429 {
1430 vRect.xLeft += 4;
1431 vRect.xRight -= 4;
1432 vRect.yTop -= 4;
1433 vRect.yBottom += 4;
1434 }
1435 else if (uStyle & FCF_SIZEBORDER)
1436 {
1437 vRect.xLeft += 4;
1438 vRect.xRight -= 4;
1439 vRect.yTop -= 4;
1440 vRect.yBottom += 4;
1441 }
1442 else if (uStyle & FCF_BORDER)
1443 {
1444 vRect.xLeft += 2;
1445 vRect.xRight -= 2;
1446 vRect.yTop -= 2;
1447 vRect.yBottom += 2;
1448 }
1449 else // make some kind of adjustment or top sizers ram into the titlebar!
1450 {
1451 vRect.xLeft += 3;
1452 vRect.xRight -= 3;
1453 vRect.yTop -= 3;
1454 vRect.yBottom += 3;
1455 }
1456 }
1457 if (pWidth)
1458 *pWidth = vRect.xRight - vRect.xLeft;
1459 if (pHeight)
1460 *pHeight = vRect.yTop - vRect.yBottom;
1461 } // end of wxWindowOS2::DoGetClientSize
1462
1463 void wxWindowOS2::DoMoveWindow(
1464 int nX
1465 , int nY
1466 , int nWidth
1467 , int nHeight
1468 )
1469 {
1470 RECTL vRect;
1471 wxWindow* pParent = GetParent();
1472
1473 /* Due to OS/2's inverted coordinate system, changing the height
1474 of a window requires repositioning all it's children, e.g. if
1475 you want a child of height 100 to be at the top left corner of
1476 the parent you need to position the lower left corner of the
1477 child at (0, (height of parent - 100)), so, obviously, if the
1478 height of the parent changes, the child needs to be repositioned. */
1479 int nHeightDelta;
1480 GetSize(0, &nHeightDelta);
1481 nHeightDelta = nHeight - nHeightDelta;
1482
1483 if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
1484 {
1485 int nOS2Height = GetOS2ParentHeight(pParent);
1486
1487 nY = nOS2Height - (nY + nHeight);
1488 }
1489 else
1490 {
1491 RECTL vRect;
1492
1493 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
1494 nY = vRect.yTop - (nY + nHeight);
1495 }
1496
1497 //
1498 // In the case of a frame whose client is sized, the client cannot be
1499 // large than its parent frame minus its borders! This usually happens
1500 // when using an autosizer to size a frame to precisely hold client
1501 // controls as in the notebook sample.
1502 //
1503 // In this case, we may need to resize both a frame and its client so we
1504 // need a quick calc of the frame border size, then if the frame
1505 // (less its borders) is smaller than the client, size the frame to
1506 // encompass the client with the appropriate border size.
1507 //
1508 if (IsKindOf(CLASSINFO(wxFrame)))
1509 {
1510 RECTL vFRect;
1511 HWND hWndFrame;
1512 int nWidthFrameDelta = 0;
1513 int nHeightFrameDelta = 0;
1514 int nHeightFrame = 0;
1515 int nWidthFrame = 0;
1516 wxFrame* pFrame;
1517
1518 pFrame = wxDynamicCast(this, wxFrame);
1519 hWndFrame = pFrame->GetFrame();
1520 ::WinQueryWindowRect(hWndFrame, &vRect);
1521 ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
1522 vFRect = vRect;
1523 ::WinCalcFrameRect(hWndFrame, &vRect, TRUE);
1524 nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight));
1525 nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop));
1526 nWidthFrame = vFRect.xRight - vFRect.xLeft;
1527 nHeightFrame = vFRect.yTop - vFRect.yBottom;
1528
1529 if (nWidth == vFRect.xRight - vFRect.xLeft &&
1530 nHeight == vFRect.yTop - vFRect.yBottom)
1531 {
1532 //
1533 // In this case the caller is not aware of OS/2's need to size both
1534 // the frame and it's client and is really only moving the window,
1535 // not resizeing it. So move the frame, and back off the sizes
1536 // for a proper client fit.
1537 //
1538 ::WinSetWindowPos( hWndFrame
1539 ,HWND_TOP
1540 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1541 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1542 ,(LONG)0
1543 ,(LONG)0
1544 ,SWP_MOVE
1545 );
1546 nX += (vRect.xLeft - vFRect.xLeft);
1547 nY += (vRect.yBottom - vFRect.yBottom);
1548 nWidth -= nWidthFrameDelta;
1549 nHeight -= nHeightFrameDelta;
1550 }
1551 else
1552 {
1553 if (nWidth > nWidthFrame - nHeightFrameDelta ||
1554 nHeight > nHeightFrame - nHeightFrameDelta)
1555 {
1556 ::WinSetWindowPos( hWndFrame
1557 ,HWND_TOP
1558 ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
1559 ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
1560 ,(LONG)nWidth + nWidthFrameDelta
1561 ,(LONG)nHeight + nHeightFrameDelta
1562 ,SWP_MOVE | SWP_SIZE
1563 );
1564 }
1565 }
1566 }
1567
1568 ::WinSetWindowPos( GetHwnd()
1569 ,HWND_TOP
1570 ,(LONG)nX
1571 ,(LONG)nY
1572 ,(LONG)nWidth
1573 ,(LONG)nHeight
1574 ,SWP_SIZE | SWP_MOVE
1575 );
1576 if (m_vWinSwp.cx == 0 && m_vWinSwp.cy == 0 && m_vWinSwp.fl == 0)
1577 //
1578 // Uninitialized
1579 //
1580 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1581 else
1582 {
1583 int nYDiff = m_vWinSwp.cy - nHeight;
1584
1585 //
1586 // Handle resizing of scrolled windows. The target or window to
1587 // be scrolled is the owner (gets the scroll notificaitons). The
1588 // parent is usually the parent frame of the scrolled panel window.
1589 // In order to show the scrollbars the target window will be shrunk
1590 // by the size of the scroll bar widths (20) and moved in the X and Y
1591 // directon. That value will be computed as part of the diff for
1592 // moving the children. Everytime the window is sized the
1593 // toplevel OnSize is going to resize the panel to fit the client
1594 // or the whole sizer and will need to me resized. This will send
1595 // a WM_SIZE out which will be intercepted by the ScrollHelper
1596 // which will cause the scrollbars to be displayed via the SetScrollbar
1597 // call in CWindow.
1598 //
1599 if ( IsKindOf(CLASSINFO(wxGenericScrolledWindow)) ||
1600 IsKindOf(CLASSINFO(wxScrolledWindow))
1601 )
1602 {
1603 int nAdjustWidth = 0;
1604 int nAdjustHeight = 0;
1605 SWP vSwpScroll;
1606
1607 if (GetScrollBarHorz() == NULLHANDLE ||
1608 !WinIsWindowShowing(GetScrollBarHorz()))
1609 nAdjustHeight = 0L;
1610 else
1611 nAdjustHeight = 20L;
1612 if (GetScrollBarVert() == NULLHANDLE ||
1613 !WinIsWindowShowing(GetScrollBarVert()))
1614 nAdjustWidth = 0L;
1615 else
1616 nAdjustWidth = 20L;
1617 ::WinQueryWindowPos(GetHWND(), &vSwpScroll);
1618 ::WinSetWindowPos( GetHWND()
1619 ,HWND_TOP
1620 ,vSwpScroll.x
1621 ,vSwpScroll.y + nAdjustHeight
1622 ,vSwpScroll.cx - nAdjustWidth
1623 ,vSwpScroll.cy - nAdjustHeight
1624 ,SWP_MOVE | SWP_SIZE
1625 );
1626 nYDiff += nAdjustHeight;
1627 }
1628 MoveChildren(nYDiff);
1629 ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
1630 }
1631 MoveChildren(nHeightDelta);
1632 } // end of wxWindowOS2::DoMoveWindow
1633
1634 //
1635 // Set the size of the window: if the dimensions are positive, just use them,
1636 // but if any of them is equal to -1, it means that we must find the value for
1637 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
1638 // which case -1 is a valid value for x and y)
1639 //
1640 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
1641 // the width/height to best suit our contents, otherwise we reuse the current
1642 // width/height
1643 //
1644 void wxWindowOS2::DoSetSize(
1645 int nX
1646 , int nY
1647 , int nWidth
1648 , int nHeight
1649 , int nSizeFlags
1650 )
1651 {
1652 //
1653 // Get the current size and position...
1654 //
1655 int nCurrentX;
1656 int nCurrentY;
1657 int nCurrentWidth;
1658 int nCurrentHeight;
1659 wxSize vSize(-1, -1);
1660
1661 GetPosition(&nCurrentX, &nCurrentY);
1662 GetSize(&nCurrentWidth, &nCurrentHeight);
1663
1664 //
1665 // ... and don't do anything (avoiding flicker) if it's already ok
1666 //
1667 //
1668 // Must convert Y coords to test for equality under OS/2
1669 //
1670 int nY2 = nY;
1671
1672 if (nX == nCurrentX && nY2 == nCurrentY &&
1673 nWidth == nCurrentWidth && nHeight == nCurrentHeight)
1674 {
1675 return;
1676 }
1677
1678 if (nX == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1679 nX = nCurrentX;
1680 if (nY == -1 && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1681 nY = nCurrentY;
1682
1683 AdjustForParentClientOrigin(nX, nY, nSizeFlags);
1684
1685 if (nWidth == -1)
1686 {
1687 if (nSizeFlags & wxSIZE_AUTO_WIDTH)
1688 {
1689 vSize = DoGetBestSize();
1690 nWidth = vSize.x;
1691 }
1692 else
1693 {
1694 //
1695 // Just take the current one
1696 //
1697 nWidth = nCurrentWidth;
1698 }
1699 }
1700
1701 if (nHeight == -1)
1702 {
1703 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
1704 {
1705 if (vSize.x == -1)
1706 {
1707 vSize = DoGetBestSize();
1708 }
1709 nHeight = vSize.y;
1710 }
1711 else
1712 {
1713 // just take the current one
1714 nHeight = nCurrentHeight;
1715 }
1716 }
1717
1718 DoMoveWindow( nX
1719 ,nY
1720 ,nWidth
1721 ,nHeight
1722 );
1723 } // end of wxWindowOS2::DoSetSize
1724
1725 void wxWindowOS2::DoSetClientSize(
1726 int nWidth
1727 , int nHeight
1728 )
1729 {
1730 POINTL vPoint;
1731 int nActualWidth;
1732 int nActualHeight;
1733 wxWindow* pParent = (wxWindow*)GetParent();
1734 HWND hParentWnd = (HWND)0;
1735
1736 if (pParent)
1737 hParentWnd = (HWND)pParent->GetHWND();
1738
1739 if (IsKindOf(CLASSINFO(wxFrame)))
1740 {
1741 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
1742 HWND hFrame = pFrame->GetFrame();
1743 RECTL vRect;
1744 RECTL vRect2;
1745 RECTL vRect3;
1746
1747 ::WinQueryWindowRect(GetHwnd(), &vRect2);
1748 ::WinQueryWindowRect(hFrame, &vRect);
1749 ::WinQueryWindowRect(hParentWnd, &vRect3);
1750 nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
1751 nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
1752
1753 vPoint.x = vRect2.xLeft;
1754 vPoint.y = vRect2.yBottom;
1755 if (pParent)
1756 {
1757 vPoint.x -= vRect3.xLeft;
1758 vPoint.y -= vRect3.yBottom;
1759 }
1760 }
1761 else
1762 {
1763 int nX;
1764 int nY;
1765
1766 GetPosition(&nX, &nY);
1767 nActualWidth = nWidth;
1768 nActualHeight = nHeight;
1769
1770 vPoint.x = nX;
1771 vPoint.y = nY;
1772 }
1773 DoMoveWindow( vPoint.x
1774 ,vPoint.y
1775 ,nActualWidth
1776 ,nActualHeight
1777 );
1778
1779 wxSizeEvent vEvent( wxSize( nWidth
1780 ,nHeight
1781 )
1782 ,m_windowId
1783 );
1784
1785 vEvent.SetEventObject(this);
1786 GetEventHandler()->ProcessEvent(vEvent);
1787 } // end of wxWindowOS2::DoSetClientSize
1788
1789 wxPoint wxWindowOS2::GetClientAreaOrigin() const
1790 {
1791 return wxPoint(0, 0);
1792 } // end of wxWindowOS2::GetClientAreaOrigin
1793
1794 // ---------------------------------------------------------------------------
1795 // text metrics
1796 // ---------------------------------------------------------------------------
1797
1798 int wxWindowOS2::GetCharHeight() const
1799 {
1800 HPS hPs;
1801 FONTMETRICS vFontMetrics;
1802
1803 hPs = ::WinGetPS(GetHwnd());
1804
1805 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
1806 {
1807 ::WinReleasePS(hPs);
1808 return (0);
1809 }
1810 ::WinReleasePS(hPs);
1811 return(vFontMetrics.lMaxAscender + vFontMetrics.lMaxDescender);
1812 } // end of wxWindowOS2::GetCharHeight
1813
1814 int wxWindowOS2::GetCharWidth() const
1815 {
1816 HPS hPs;
1817 FONTMETRICS vFontMetrics;
1818
1819 hPs = ::WinGetPS(GetHwnd());
1820
1821 if(!GpiQueryFontMetrics(hPs, sizeof(FONTMETRICS), &vFontMetrics))
1822 {
1823 ::WinReleasePS(hPs);
1824 return (0);
1825 }
1826 ::WinReleasePS(hPs);
1827 return(vFontMetrics.lAveCharWidth);
1828 } // end of wxWindowOS2::GetCharWidth
1829
1830 void wxWindowOS2::GetTextExtent(
1831 const wxString& rString
1832 , int* pX
1833 , int* pY
1834 , int* pDescent
1835 , int* pExternalLeading
1836 , const wxFont* pTheFont
1837 ) const
1838 {
1839 POINTL avPoint[TXTBOX_COUNT];
1840 POINTL vPtMin;
1841 POINTL vPtMax;
1842 int i;
1843 int l;
1844 FONTMETRICS vFM; // metrics structure
1845 BOOL bRc = FALSE;
1846 char* pStr;
1847 HPS hPS;
1848
1849
1850 hPS = ::WinGetPS(GetHwnd());
1851
1852 l = rString.Length();
1853 if (l > 0L)
1854 {
1855 pStr = (PCH)rString.c_str();
1856
1857 //
1858 // In world coordinates.
1859 //
1860 bRc = ::GpiQueryTextBox( hPS
1861 ,l
1862 ,pStr
1863 ,TXTBOX_COUNT // return maximum information
1864 ,avPoint // array of coordinates points
1865 );
1866 if (bRc)
1867 {
1868 vPtMin.x = avPoint[0].x;
1869 vPtMax.x = avPoint[0].x;
1870 vPtMin.y = avPoint[0].y;
1871 vPtMax.y = avPoint[0].y;
1872 for (i = 1; i < 4; i++)
1873 {
1874 if(vPtMin.x > avPoint[i].x) vPtMin.x = avPoint[i].x;
1875 if(vPtMin.y > avPoint[i].y) vPtMin.y = avPoint[i].y;
1876 if(vPtMax.x < avPoint[i].x) vPtMax.x = avPoint[i].x;
1877 if(vPtMax.y < avPoint[i].y) vPtMax.y = avPoint[i].y;
1878 }
1879 bRc = ::GpiQueryFontMetrics( hPS
1880 ,sizeof(FONTMETRICS)
1881 ,&vFM
1882 );
1883 if (!bRc)
1884 {
1885 vPtMin.x = 0;
1886 vPtMin.y = 0;
1887 vPtMax.x = 0;
1888 vPtMax.y = 0;
1889 }
1890 }
1891 else
1892 {
1893 vPtMin.x = 0;
1894 vPtMin.y = 0;
1895 vPtMax.x = 0;
1896 vPtMax.y = 0;
1897 }
1898 }
1899 else
1900 {
1901 vPtMin.x = 0;
1902 vPtMin.y = 0;
1903 vPtMax.x = 0;
1904 vPtMax.y = 0;
1905 }
1906 if (pX)
1907 *pX = (vPtMax.x - vPtMin.x + 1);
1908 if (pY)
1909 *pY = (vPtMax.y - vPtMin.y + 1);
1910 if (pDescent)
1911 {
1912 if (bRc)
1913 *pDescent = vFM.lMaxDescender;
1914 else
1915 *pDescent = 0;
1916 }
1917 if (pExternalLeading)
1918 {
1919 if (bRc)
1920 *pExternalLeading = vFM.lExternalLeading;
1921 else
1922 *pExternalLeading = 0;
1923 }
1924 ::WinReleasePS(hPS);
1925 } // end of wxWindow::GetTextExtent
1926
1927 bool wxWindowOS2::IsMouseInWindow() const
1928 {
1929 //
1930 // Get the mouse position
1931 POINTL vPt;
1932
1933 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
1934
1935 //
1936 // Find the window which currently has the cursor and go up the window
1937 // chain until we find this window - or exhaust it
1938 //
1939 HWND hWnd = ::WinWindowFromPoint(HWND_DESKTOP, &vPt, TRUE);
1940
1941 while (hWnd && (hWnd != GetHwnd()))
1942 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
1943
1944 return hWnd != NULL;
1945 } // end of wxWindowOS2::IsMouseInWindow
1946
1947
1948 // ---------------------------------------------------------------------------
1949 // popup menu
1950 // ---------------------------------------------------------------------------
1951 //
1952 #if wxUSE_MENUS_NATIVE
1953 bool wxWindowOS2::DoPopupMenu(
1954 wxMenu* pMenu
1955 , int nX
1956 , int nY
1957 )
1958 {
1959 HWND hWndOwner = GetHwnd();
1960 HWND hWndParent = GetHwnd();
1961 HWND hMenu = GetHmenuOf(pMenu);
1962 bool bIsWaiting = TRUE;
1963 int nHeight;
1964
1965 // Protect against recursion
1966 if (wxCurrentPopupMenu)
1967 return false;
1968
1969 pMenu->SetInvokingWindow(this);
1970 pMenu->UpdateUI();
1971
1972 if ( nX == -1 && nY == -1 )
1973 {
1974 wxPoint mouse = wxGetMousePosition();
1975 nX = mouse.x; nY = mouse.y;
1976 }
1977 else
1978 {
1979 DoClientToScreen( &nX
1980 ,&nY
1981 );
1982 DoGetSize(0,&nHeight);
1983 nY = nHeight - nY;
1984 }
1985 wxCurrentPopupMenu = pMenu;
1986
1987 ::WinPopupMenu( hWndParent
1988 ,hWndOwner
1989 ,hMenu
1990 ,nX
1991 ,nY
1992 ,0L
1993 ,PU_HCONSTRAIN | PU_VCONSTRAIN | PU_MOUSEBUTTON1 | PU_KEYBOARD
1994 );
1995
1996 while(bIsWaiting)
1997 {
1998 QMSG vMsg;
1999
2000 ::WinGetMsg(vHabmain,&vMsg, (HWND)0, 0, 0);
2001 if (vMsg.msg == WM_COMMAND)
2002 bIsWaiting = FALSE;
2003 ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
2004 }
2005
2006 wxCurrentPopupMenu = NULL;
2007 pMenu->SetInvokingWindow(NULL);
2008 return TRUE;
2009 } // end of wxWindowOS2::DoPopupMenu
2010 #endif // wxUSE_MENUS_NATIVE
2011
2012 // ===========================================================================
2013 // pre/post message processing
2014 // ===========================================================================
2015
2016 MRESULT wxWindowOS2::OS2DefWindowProc(
2017 WXUINT uMsg
2018 , WXWPARAM wParam
2019 , WXLPARAM lParam
2020 )
2021 {
2022 if (m_fnOldWndProc)
2023 return (MRESULT)m_fnOldWndProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
2024 else
2025 return ::WinDefWindowProc(GetHWND(), uMsg, (MPARAM)wParam, (MPARAM)lParam);
2026 } // end of wxWindowOS2::OS2DefWindowProc
2027
2028 bool wxWindowOS2::OS2ProcessMessage(
2029 WXMSG* pMsg
2030 )
2031 {
2032 // wxUniversal implements tab traversal itself
2033 #ifndef __WXUNIVERSAL__
2034 QMSG* pQMsg = (QMSG*)pMsg;
2035
2036 if (m_hWnd != 0 && (GetWindowStyleFlag() & wxTAB_TRAVERSAL))
2037 {
2038 //
2039 // Intercept dialog navigation keys
2040 //
2041 bool bProcess = TRUE;
2042 USHORT uKeyFlags = SHORT1FROMMP(pQMsg->mp1);
2043
2044 if (uKeyFlags & KC_KEYUP)
2045 bProcess = FALSE;
2046
2047 if (uKeyFlags & KC_ALT)
2048 bProcess = FALSE;
2049
2050 if (!(uKeyFlags & KC_VIRTUALKEY))
2051 bProcess = FALSE;
2052
2053 if (bProcess)
2054 {
2055 bool bCtrlDown = IsCtrlDown();
2056 bool bShiftDown = IsShiftDown();
2057
2058 //
2059 // WM_QUERYDLGCODE: ask the control if it wants the key for itself,
2060 // don't process it if it's the case (except for Ctrl-Tab/Enter
2061 // combinations which are always processed)
2062 //
2063 ULONG ulDlgCode = 0;
2064
2065 if (!bCtrlDown)
2066 {
2067 ulDlgCode = (ULONG)::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0);
2068 }
2069
2070 bool bForward = TRUE;
2071 bool bWindowChange = FALSE;
2072
2073 switch (SHORT2FROMMP(pQMsg->mp2))
2074 {
2075 //
2076 // Going to make certain assumptions about specific types of controls
2077 // here, so we may have to alter some things later if they prove invalid
2078 //
2079 case VK_TAB:
2080 //
2081 // Shift tabl will always be a nav-key but tabs may be wanted
2082 //
2083 if (!bShiftDown)
2084 {
2085 bProcess = FALSE;
2086 }
2087 else
2088 {
2089 //
2090 // Entry Fields want tabs for themselve usually
2091 //
2092 switch (ulDlgCode)
2093 {
2094 case DLGC_ENTRYFIELD:
2095 case DLGC_MLE:
2096 bProcess = TRUE;
2097 break;
2098
2099 default:
2100 bProcess = FALSE;
2101 }
2102
2103 //
2104 // Ctrl-Tab cycles thru notebook pages
2105 //
2106 bWindowChange = bCtrlDown;
2107 bForward = !bShiftDown;
2108 }
2109 break;
2110
2111 case VK_UP:
2112 case VK_LEFT:
2113 if (bCtrlDown)
2114 bProcess = FALSE;
2115 else
2116 bForward = FALSE;
2117 break;
2118
2119 case VK_DOWN:
2120 case VK_RIGHT:
2121 if (bCtrlDown)
2122 bProcess = FALSE;
2123 break;
2124
2125 case VK_ENTER:
2126 {
2127 if (bCtrlDown)
2128 {
2129 //
2130 // ctrl-enter is not processed
2131 //
2132 return FALSE;
2133 }
2134 else if (ulDlgCode & DLGC_BUTTON)
2135 {
2136 //
2137 // buttons want process Enter themselevs
2138 //
2139 bProcess = FALSE;
2140 }
2141 else
2142 {
2143 wxButton* pBtn = wxDynamicCast( GetDefaultItem()
2144 ,wxButton
2145 );
2146
2147 if (pBtn && pBtn->IsEnabled())
2148 {
2149 //
2150 // If we do have a default button, do press it
2151 //
2152 pBtn->OS2Command(BN_CLICKED, 0 /* unused */);
2153 return TRUE;
2154 }
2155 else if (!IsTopLevel())
2156 {
2157 //
2158 // if not a top level window, let parent
2159 // handle it
2160 //
2161 return FALSE;
2162 }
2163 // else: but if it does not it makes sense to make
2164 // it work like a TAB - and that's what we do.
2165 // Note that Ctrl-Enter always works this way.
2166 }
2167 }
2168 break;
2169
2170 default:
2171 bProcess = FALSE;
2172 }
2173
2174 if (bProcess)
2175 {
2176 wxNavigationKeyEvent vEvent;
2177
2178 vEvent.SetDirection(bForward);
2179 vEvent.SetWindowChange(bWindowChange);
2180 vEvent.SetEventObject(this);
2181
2182 if (GetEventHandler()->ProcessEvent(vEvent))
2183 {
2184 wxButton* pBtn = wxDynamicCast(FindFocus(), wxButton);
2185
2186 if (pBtn)
2187 {
2188 //
2189 // The button which has focus should be default
2190 //
2191 pBtn->SetDefault();
2192 }
2193 return TRUE;
2194 }
2195 }
2196 }
2197 //
2198 // Let Dialogs process
2199 //
2200 if (::WinSendMsg(pQMsg->hwnd, WM_QUERYDLGCODE, pQMsg, 0));
2201 return TRUE;
2202 }
2203 #else
2204 pMsg = pMsg; // just shut up the compiler
2205 #endif // __WXUNIVERSAL__
2206
2207 return FALSE;
2208 } // end of wxWindowOS2::OS2ProcessMessage
2209
2210 bool wxWindowOS2::OS2TranslateMessage(
2211 WXMSG* pMsg
2212 )
2213 {
2214 #if wxUSE_ACCEL && !defined(__WXUNIVERSAL__)
2215 return m_acceleratorTable.Translate(m_hWnd, pMsg);
2216 #else
2217 pMsg = pMsg;
2218 return FALSE;
2219 #endif //wxUSE_ACCEL
2220 } // end of wxWindowOS2::OS2TranslateMessage
2221
2222 bool wxWindowOS2::OS2ShouldPreProcessMessage(
2223 WXMSG* pMsg
2224 )
2225 {
2226 // preprocess all messages by default
2227 return TRUE;
2228 } // end of wxWindowOS2::OS2ShouldPreProcessMessage
2229
2230 // ---------------------------------------------------------------------------
2231 // message params unpackers
2232 // ---------------------------------------------------------------------------
2233
2234 void wxWindowOS2::UnpackCommand(
2235 WXWPARAM wParam
2236 , WXLPARAM lParam
2237 , WORD* pId
2238 , WXHWND* phWnd
2239 , WORD* pCmd
2240 )
2241 {
2242 *pId = LOWORD(wParam);
2243 *phWnd = NULL; // or may be GetHWND() ?
2244 *pCmd = LOWORD(lParam);
2245 } // end of wxWindowOS2::UnpackCommand
2246
2247 void wxWindowOS2::UnpackActivate(
2248 WXWPARAM wParam
2249 , WXLPARAM lParam
2250 , WXWORD* pState
2251 , WXHWND* phWnd
2252 )
2253 {
2254 *pState = LOWORD(wParam);
2255 *phWnd = (WXHWND)lParam;
2256 } // end of wxWindowOS2::UnpackActivate
2257
2258 void wxWindowOS2::UnpackScroll(
2259 WXWPARAM wParam
2260 , WXLPARAM lParam
2261 , WXWORD* pCode
2262 , WXWORD* pPos
2263 , WXHWND* phWnd
2264 )
2265 {
2266 ULONG ulId;
2267 HWND hWnd;
2268
2269 ulId = (ULONG)LONGFROMMP(wParam);
2270 hWnd = ::WinWindowFromID(GetHwnd(), ulId);
2271 if (hWnd == m_hWndScrollBarHorz || hWnd == m_hWndScrollBarVert)
2272 *phWnd = NULLHANDLE;
2273 else
2274 *phWnd = hWnd;
2275
2276 *pPos = SHORT1FROMMP(lParam);
2277 *pCode = SHORT2FROMMP(lParam);
2278 } // end of wxWindowOS2::UnpackScroll
2279
2280 void wxWindowOS2::UnpackMenuSelect(
2281 WXWPARAM wParam
2282 , WXLPARAM lParam
2283 , WXWORD* pItem
2284 , WXWORD* pFlags
2285 , WXHMENU* phMenu
2286 )
2287 {
2288 *pItem = (WXWORD)LOWORD(wParam);
2289 *pFlags = HIWORD(wParam);
2290 *phMenu = (WXHMENU)lParam;
2291 } // end of wxWindowOS2::UnpackMenuSelect
2292
2293 // ---------------------------------------------------------------------------
2294 // Main wxWidgets window proc and the window proc for wxWindow
2295 // ---------------------------------------------------------------------------
2296
2297 //
2298 // Hook for new window just as it's being created, when the window isn't yet
2299 // associated with the handle
2300 //
2301 wxWindowOS2* wxWndHook = NULL;
2302
2303 //
2304 // Main window proc
2305 //
2306 MRESULT EXPENTRY wxWndProc(
2307 HWND hWnd
2308 , ULONG ulMsg
2309 , MPARAM wParam
2310 , MPARAM lParam
2311 )
2312 {
2313 wxWindowOS2* pWnd = wxFindWinFromHandle((WXHWND)hWnd);
2314
2315 //
2316 // When we get the first message for the HWND we just created, we associate
2317 // it with wxWindow stored in wxWndHook
2318 //
2319 if (!pWnd && wxWndHook)
2320 {
2321 wxAssociateWinWithHandle(hWnd, wxWndHook);
2322 pWnd = wxWndHook;
2323 wxWndHook = NULL;
2324 pWnd->SetHWND((WXHWND)hWnd);
2325 }
2326
2327 MRESULT rc = (MRESULT)0;
2328
2329
2330 //
2331 // Stop right here if we don't have a valid handle in our wxWindow object.
2332 //
2333 if (pWnd && !pWnd->GetHWND())
2334 {
2335 pWnd->SetHWND((WXHWND) hWnd);
2336 rc = pWnd->OS2DefWindowProc(ulMsg, wParam, lParam );
2337 pWnd->SetHWND(0);
2338 }
2339 else
2340 {
2341 if (pWnd)
2342 {
2343 rc = pWnd->OS2WindowProc(ulMsg, wParam, lParam);
2344 if ( (pWnd->GetScrollBarHorz() != NULLHANDLE ||
2345 pWnd->GetScrollBarVert() != NULLHANDLE) &&
2346 ulMsg == WM_PAINT)
2347 {
2348 if (pWnd->GetScrollBarHorz() != NULLHANDLE)
2349 ::WinInvalidateRect(pWnd->GetScrollBarHorz(), NULL, TRUE);
2350 if (pWnd->GetScrollBarVert() != NULLHANDLE)
2351 ::WinInvalidateRect(pWnd->GetScrollBarVert(), NULL, TRUE);
2352 }
2353 }
2354 else
2355 rc = ::WinDefWindowProc(hWnd, ulMsg, wParam, lParam);
2356 }
2357
2358 return rc;
2359 } // end of wxWndProc
2360
2361 //
2362 // We will add (or delete) messages we need to handle at this default
2363 // level as we go
2364 //
2365 MRESULT wxWindowOS2::OS2WindowProc(
2366 WXUINT uMsg
2367 , WXWPARAM wParam
2368 , WXLPARAM lParam
2369 )
2370 {
2371 //
2372 // Did we process the uMsg?
2373 //
2374 bool bProcessed = FALSE;
2375 MRESULT mResult;
2376
2377 //
2378 // For most messages we should return 0 when we do process the message
2379 //
2380 mResult = (MRESULT)0;
2381
2382 switch (uMsg)
2383 {
2384 case WM_CREATE:
2385 {
2386 bool bMayCreate;
2387
2388 bProcessed = HandleCreate( (WXLPCREATESTRUCT)lParam
2389 ,&bMayCreate
2390 );
2391 if (bProcessed)
2392 {
2393 //
2394 // Return 0 to bAllow window creation
2395 //
2396 mResult = (MRESULT)(bMayCreate ? 0 : -1);
2397 }
2398 }
2399 break;
2400
2401 case WM_DESTROY:
2402 HandleDestroy();
2403 bProcessed = TRUE;
2404 break;
2405
2406 case WM_MOVE:
2407 bProcessed = HandleMove( LOWORD(lParam)
2408 ,HIWORD(lParam)
2409 );
2410 break;
2411
2412 case WM_SIZE:
2413 bProcessed = HandleSize( LOWORD(lParam)
2414 ,HIWORD(lParam)
2415 ,(WXUINT)wParam
2416 );
2417 break;
2418
2419 case WM_WINDOWPOSCHANGED:
2420
2421 //
2422 // Dialogs under OS/2 do not get WM_SIZE events at all.
2423 // Instead they get this, which can function much like WM_SIZE
2424 // PSWP contains the new sizes and positioning, PSWP+1 the old
2425 // We use this because ADJUSTWINDOWPOS comes BEFORE the new
2426 // position is added and our auto layout does a WinQueryWindowRect
2427 // to get the CURRENT client size. That is the size used to position
2428 // child controls, so we need to already be sized
2429 // in order to get the child controls positoned properly.
2430 //
2431 if (IsKindOf(CLASSINFO(wxDialog)) || IsKindOf(CLASSINFO(wxFrame)))
2432 {
2433 PSWP pSwp = (PSWP)PVOIDFROMMP(wParam);
2434 PSWP pSwp2 = pSwp++;
2435
2436 if (!(pSwp->cx == pSwp2->cx &&
2437 pSwp->cy == pSwp2->cy))
2438 bProcessed = HandleSize( pSwp->cx
2439 ,pSwp->cy
2440 ,(WXUINT)lParam
2441 );
2442 if (IsKindOf(CLASSINFO(wxFrame)))
2443 {
2444 wxFrame* pFrame = wxDynamicCast(this, wxFrame);
2445
2446 if (pFrame)
2447 {
2448 if (pFrame->GetStatusBar())
2449 pFrame->PositionStatusBar();
2450 if (pFrame->GetToolBar())
2451 pFrame->PositionToolBar();
2452 }
2453 }
2454 }
2455 break;
2456
2457 case WM_ACTIVATE:
2458 {
2459 WXWORD wState;
2460 WXHWND hWnd;
2461
2462 UnpackActivate( wParam
2463 ,lParam
2464 ,&wState
2465 ,&hWnd
2466 );
2467
2468 bProcessed = HandleActivate( wState
2469 ,(WXHWND)hWnd
2470 );
2471 bProcessed = FALSE;
2472 }
2473 break;
2474
2475 case WM_SETFOCUS:
2476 if (SHORT1FROMMP((MPARAM)lParam) == TRUE)
2477 bProcessed = HandleSetFocus((WXHWND)(HWND)wParam);
2478 else
2479 bProcessed = HandleKillFocus((WXHWND)(HWND)wParam);
2480 break;
2481
2482 case WM_PAINT:
2483 bProcessed = HandlePaint();
2484 break;
2485
2486 case WM_CLOSE:
2487 //
2488 // Don't let the DefWindowProc() destroy our window - we'll do it
2489 // ourselves in ~wxWindow
2490 //
2491 bProcessed = TRUE;
2492 mResult = (MRESULT)TRUE;
2493 break;
2494
2495 case WM_SHOW:
2496 bProcessed = HandleShow(wParam != 0, (int)lParam);
2497 break;
2498
2499 //
2500 // Under OS2 PM Joysticks are treated just like mouse events
2501 // The "Motion" events will be prevelent in joysticks
2502 //
2503 case WM_MOUSEMOVE:
2504 case WM_BUTTON1DOWN:
2505 case WM_BUTTON1UP:
2506 case WM_BUTTON1DBLCLK:
2507 case WM_BUTTON1MOTIONEND:
2508 case WM_BUTTON1MOTIONSTART:
2509 case WM_BUTTON2DOWN:
2510 case WM_BUTTON2UP:
2511 case WM_BUTTON2DBLCLK:
2512 case WM_BUTTON2MOTIONEND:
2513 case WM_BUTTON2MOTIONSTART:
2514 case WM_BUTTON3DOWN:
2515 case WM_BUTTON3UP:
2516 case WM_BUTTON3DBLCLK:
2517 case WM_BUTTON3MOTIONEND:
2518 case WM_BUTTON3MOTIONSTART:
2519 {
2520 if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
2521 SetFocus();
2522
2523 short nX = LOWORD(wParam);
2524 short nY = HIWORD(wParam);
2525
2526 //
2527 // Redirect the event to a static control if necessary
2528 //
2529 if (this == GetCapture())
2530 {
2531 bProcessed = HandleMouseEvent( uMsg
2532 ,nX
2533 ,nY
2534 ,(WXUINT)SHORT2FROMMP(lParam)
2535 );
2536 }
2537 else
2538 {
2539 wxWindow* pWin = FindWindowForMouseEvent( this
2540 ,&nX
2541 ,&nY
2542 );
2543 if (!pWin->IsOfStandardClass())
2544 {
2545 if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
2546 pWin->SetFocus();
2547 }
2548 bProcessed = pWin->HandleMouseEvent( uMsg
2549 ,nX
2550 ,nY
2551 ,(WXUINT)SHORT2FROMMP(lParam)
2552 );
2553 }
2554 }
2555 break;
2556
2557 case WM_SYSCOMMAND:
2558 bProcessed = HandleSysCommand(wParam, lParam);
2559 break;
2560
2561 case WM_COMMAND:
2562 {
2563 WORD id, cmd;
2564 WXHWND hwnd;
2565 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
2566
2567 bProcessed = HandleCommand(id, cmd, hwnd);
2568 }
2569 break;
2570
2571 //
2572 // For these messages we must return TRUE if process the message
2573 //
2574 case WM_DRAWITEM:
2575 case WM_MEASUREITEM:
2576 {
2577 int nIdCtrl = (UINT)wParam;
2578
2579 if ( uMsg == WM_DRAWITEM )
2580 {
2581 bProcessed = OS2OnDrawItem(nIdCtrl,
2582 (WXDRAWITEMSTRUCT *)lParam);
2583 }
2584 else
2585 {
2586 return MRFROMLONG(OS2OnMeasureItem( nIdCtrl
2587 ,(WXMEASUREITEMSTRUCT *)lParam
2588 ));
2589 }
2590
2591 if ( bProcessed )
2592 mResult = (MRESULT)TRUE;
2593 }
2594 break;
2595
2596 case WM_QUERYDLGCODE:
2597 if (!IsOfStandardClass())
2598 {
2599 if ( m_lDlgCode )
2600 {
2601 mResult = (MRESULT)m_lDlgCode;
2602 bProcessed = TRUE;
2603 }
2604 }
2605 //
2606 //else: get the dlg code from the DefWindowProc()
2607 //
2608 break;
2609
2610 //
2611 // In OS/2 PM all keyboard events are of the WM_CHAR type. Virtual key and key-up
2612 // and key-down events are obtained from the WM_CHAR params.
2613 //
2614 case WM_CHAR:
2615 {
2616 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
2617
2618 if (uKeyFlags & KC_KEYUP)
2619 {
2620 //TODO: check if the cast to WXWORD isn't causing trouble
2621 bProcessed = HandleKeyUp(wParam, lParam);
2622 break;
2623 }
2624 else // keydown event
2625 {
2626 m_bLastKeydownProcessed = FALSE;
2627 //
2628 // If this has been processed by an event handler,
2629 // return 0 now (we've handled it). DON't RETURN
2630 // we still need to process further
2631 //
2632 m_bLastKeydownProcessed = HandleKeyDown(wParam, lParam);
2633 if (uKeyFlags & KC_VIRTUALKEY)
2634 {
2635 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
2636
2637 //
2638 // We consider these message "not interesting" to OnChar
2639 //
2640 switch(uVk)
2641 {
2642 case VK_SHIFT:
2643 case VK_CTRL:
2644 case VK_MENU:
2645 case VK_CAPSLOCK:
2646 case VK_NUMLOCK:
2647 case VK_SCRLLOCK:
2648 bProcessed = TRUE;
2649 break;
2650
2651 // Avoid duplicate messages to OnChar for these ASCII keys: they
2652 // will be translated by TranslateMessage() and received in WM_CHAR
2653 case VK_ESC:
2654 case VK_ENTER:
2655 case VK_BACKSPACE:
2656 case VK_TAB:
2657 // But set processed to FALSE, not TRUE to still pass them to
2658 // the control's default window proc - otherwise built-in
2659 // keyboard handling won't work
2660 bProcessed = FALSE;
2661 break;
2662
2663 default:
2664 bProcessed = HandleChar(wParam, lParam);
2665 }
2666 break;
2667 }
2668 else // WM_CHAR -- Always an ASCII character
2669 {
2670 if (m_bLastKeydownProcessed)
2671 {
2672 //
2673 // The key was handled in the EVT_KEY_DOWN and handling
2674 // a key in an EVT_KEY_DOWN handler is meant, by
2675 // design, to prevent EVT_CHARs from happening
2676 //
2677 m_bLastKeydownProcessed = FALSE;
2678 bProcessed = TRUE;
2679 }
2680 else // do generate a CHAR event
2681 {
2682 bProcessed = HandleChar(wParam, lParam, TRUE);
2683 break;
2684 }
2685 }
2686 }
2687 }
2688
2689 case WM_HSCROLL:
2690 case WM_VSCROLL:
2691 {
2692 WXWORD wCode;
2693 WXWORD wPos;
2694 WXHWND hWnd;
2695 UnpackScroll( wParam
2696 ,lParam
2697 ,&wCode
2698 ,&wPos
2699 ,&hWnd
2700 );
2701
2702 bProcessed = OS2OnScroll( uMsg == WM_HSCROLL ? wxHORIZONTAL
2703 : wxVERTICAL
2704 ,wCode
2705 ,wPos
2706 ,hWnd
2707 );
2708 }
2709 break;
2710
2711 case WM_CONTROL:
2712 switch(SHORT2FROMMP(wParam))
2713 {
2714 case BN_PAINT:
2715 {
2716 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2717 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2718
2719 if (!pWin)
2720 {
2721 bProcessed = FALSE;
2722 break;
2723 }
2724 if (pWin->IsKindOf(CLASSINFO(wxBitmapButton)))
2725 {
2726 wxBitmapButton* pBitmapButton = wxDynamicCast(pWin, wxBitmapButton);
2727
2728 pBitmapButton->OS2OnDraw((WXDRAWITEMSTRUCT *)lParam);
2729 }
2730 return 0;
2731 }
2732 break;
2733
2734 case BKN_PAGESELECTEDPENDING:
2735 {
2736 PPAGESELECTNOTIFY pPage = (PPAGESELECTNOTIFY)lParam;
2737
2738 if ((pPage->ulPageIdNew != pPage->ulPageIdCur) &&
2739 (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
2740 {
2741 wxWindowOS2* pWin = wxFindWinFromHandle(pPage->hwndBook);
2742 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
2743 ,(int)SHORT1FROMMP(wParam)
2744 ,(int)pPage->ulPageIdNew
2745 ,(int)pPage->ulPageIdCur
2746 );
2747 if (!pWin)
2748 {
2749 bProcessed = FALSE;
2750 break;
2751 }
2752 if (pWin->IsKindOf(CLASSINFO(wxNotebook)))
2753 {
2754 wxNotebook* pNotebook = wxDynamicCast(pWin, wxNotebook);
2755
2756 vEvent.SetEventObject(pWin);
2757 pNotebook->OnSelChange(vEvent);
2758 bProcessed = TRUE;
2759 }
2760 else
2761 bProcessed = FALSE;
2762 }
2763 else
2764 bProcessed = FALSE;
2765 }
2766 break;
2767
2768 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
2769 {
2770 HWND hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
2771 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2772
2773 if (!pWin)
2774 {
2775 bProcessed = FALSE;
2776 break;
2777 }
2778 //
2779 // Simulate a WM_COMMAND here, as wxWidgets expects all control
2780 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2781 //
2782 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
2783 {
2784 wxRadioBox* pRadioBox = wxDynamicCast(pWin, wxRadioBox);
2785
2786 pRadioBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2787 ,(WXUINT)SHORT1FROMMP(wParam)
2788 );
2789 }
2790 if (pWin->IsKindOf(CLASSINFO(wxRadioButton)))
2791 {
2792 wxRadioButton* pRadioButton = wxDynamicCast(pWin, wxRadioButton);
2793
2794 pRadioButton->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2795 ,(WXUINT)SHORT1FROMMP(wParam)
2796 );
2797 }
2798 if (pWin->IsKindOf(CLASSINFO(wxCheckBox)))
2799 {
2800 wxCheckBox* pCheckBox = wxDynamicCast(pWin, wxCheckBox);
2801
2802 pCheckBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2803 ,(WXUINT)SHORT1FROMMP(wParam)
2804 );
2805 }
2806 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2807 {
2808 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2809
2810 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2811 ,(WXUINT)SHORT1FROMMP(wParam)
2812 );
2813 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2814 Refresh();
2815 }
2816 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2817 {
2818 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2819
2820 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2821 ,(WXUINT)SHORT1FROMMP(wParam)
2822 );
2823 }
2824 return 0;
2825 }
2826 break;
2827
2828 case LN_ENTER: /* dups as CBN_EFCHANGE */
2829 {
2830 HWND hWnd = HWNDFROMMP(lParam);
2831 wxWindowOS2* pWin = wxFindWinFromHandle(hWnd);
2832
2833 if (!pWin)
2834 {
2835 bProcessed = FALSE;
2836 break;
2837 }
2838 //
2839 // Simulate a WM_COMMAND here, as wxWidgets expects all control
2840 // button clicks to generate WM_COMMAND msgs, not WM_CONTROL
2841 //
2842 if (pWin->IsKindOf(CLASSINFO(wxListBox)))
2843 {
2844 wxListBox* pListBox = wxDynamicCast(pWin, wxListBox);
2845
2846 pListBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2847 ,(WXUINT)SHORT1FROMMP(wParam)
2848 );
2849 if (pListBox->GetWindowStyle() & wxLB_OWNERDRAW)
2850 Refresh();
2851
2852 }
2853 if (pWin->IsKindOf(CLASSINFO(wxComboBox)))
2854 {
2855 wxComboBox* pComboBox = wxDynamicCast(pWin, wxComboBox);
2856
2857 pComboBox->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
2858 ,(WXUINT)SHORT1FROMMP(wParam)
2859 );
2860 }
2861 return 0;
2862 }
2863 break;
2864
2865 case SPBN_UPARROW:
2866 case SPBN_DOWNARROW:
2867 case SPBN_CHANGE:
2868 {
2869 char zVal[10];
2870 long lVal;
2871
2872 ::WinSendMsg( HWNDFROMMP(lParam)
2873 ,SPBM_QUERYVALUE
2874 ,&zVal
2875 ,MPFROM2SHORT( (USHORT)10
2876 ,(USHORT)SPBQ_UPDATEIFVALID
2877 )
2878 );
2879 lVal = atol(zVal);
2880 bProcessed = OS2OnScroll( wxVERTICAL
2881 ,(int)SHORT2FROMMP(wParam)
2882 ,(int)lVal
2883 ,HWNDFROMMP(lParam)
2884 );
2885 }
2886 break;
2887
2888 case SLN_SLIDERTRACK:
2889 {
2890 HWND hWnd = ::WinWindowFromID(GetHWND(), SHORT1FROMMP(wParam));
2891 wxWindowOS2* pChild = wxFindWinFromHandle(hWnd);
2892
2893 if (!pChild)
2894 {
2895 bProcessed = FALSE;
2896 break;
2897 }
2898 if (pChild->IsKindOf(CLASSINFO(wxSlider)))
2899 bProcessed = OS2OnScroll( wxVERTICAL
2900 ,(int)SHORT2FROMMP(wParam)
2901 ,(int)LONGFROMMP(lParam)
2902 ,hWnd
2903 );
2904 }
2905 break;
2906 }
2907 break;
2908
2909 #if defined(__VISAGECPP__) && (__IBMCPP__ >= 400)
2910 case WM_CTLCOLORCHANGE:
2911 {
2912 bProcessed = HandleCtlColor(&hBrush);
2913 }
2914 break;
2915 #endif
2916 case WM_ERASEBACKGROUND:
2917 //
2918 // Returning TRUE to requestw PM to paint the window background
2919 // in SYSCLR_WINDOW. We don't really want that
2920 //
2921 bProcessed = HandleEraseBkgnd((WXHDC)(HPS)wParam);
2922 mResult = (MRESULT)(FALSE);
2923 break;
2924
2925 // the return value for this message is ignored
2926 case WM_SYSCOLORCHANGE:
2927 bProcessed = HandleSysColorChange();
2928 break;
2929
2930 case WM_REALIZEPALETTE:
2931 bProcessed = HandlePaletteChanged();
2932 break;
2933
2934 // move all drag and drops to wxDrg
2935 case WM_ENDDRAG:
2936 bProcessed = HandleEndDrag(wParam);
2937 break;
2938
2939 case WM_INITDLG:
2940 bProcessed = HandleInitDialog((WXHWND)(HWND)wParam);
2941
2942 if ( bProcessed )
2943 {
2944 // we never set focus from here
2945 mResult = (MRESULT)FALSE;
2946 }
2947 break;
2948
2949 // wxFrame specific message
2950 case WM_MINMAXFRAME:
2951 bProcessed = HandleGetMinMaxInfo((PSWP)wParam);
2952 break;
2953
2954 case WM_SYSVALUECHANGED:
2955 // TODO: do something
2956 mResult = (MRESULT)TRUE;
2957 break;
2958
2959 //
2960 // Comparable to WM_SETPOINTER for windows, only for just controls
2961 //
2962 case WM_CONTROLPOINTER:
2963 bProcessed = HandleSetCursor( SHORT1FROMMP(wParam) // Control ID
2964 ,(HWND)lParam // Cursor Handle
2965 );
2966 if (bProcessed )
2967 {
2968 //
2969 // Returning TRUE stops the DefWindowProc() from further
2970 // processing this message - exactly what we need because we've
2971 // just set the cursor.
2972 //
2973 mResult = (MRESULT)TRUE;
2974 }
2975 break;
2976
2977 #if wxUSE_MENUS_NATIVE
2978 case WM_MENUEND:
2979 if (wxCurrentPopupMenu)
2980 {
2981 if (GetHmenuOf(wxCurrentPopupMenu) == (HWND)lParam)
2982 {
2983 // Break out of msg loop in DoPopupMenu
2984 ::WinPostMsg((HWND)lParam,WM_COMMAND,wParam,0);
2985 }
2986 }
2987 break;
2988 #endif // wxUSE_MENUS_NATIVE
2989
2990 }
2991 if (!bProcessed)
2992 {
2993 #ifdef __WXDEBUG__
2994 wxLogTrace(wxTraceMessages, wxT("Forwarding %s to DefWindowProc."),
2995 wxGetMessageName(uMsg));
2996 #endif // __WXDEBUG__
2997 if (IsKindOf(CLASSINFO(wxFrame)))
2998 mResult = ::WinDefWindowProc(m_hWnd, uMsg, wParam, lParam);
2999 else if (IsKindOf(CLASSINFO(wxDialog)))
3000 mResult = ::WinDefDlgProc( m_hWnd, uMsg, wParam, lParam);
3001 else
3002 mResult = OS2DefWindowProc(uMsg, wParam, lParam);
3003 }
3004 return mResult;
3005 } // end of wxWindowOS2::OS2WindowProc
3006
3007 // ----------------------------------------------------------------------------
3008 // wxWindow <-> HWND map
3009 // ----------------------------------------------------------------------------
3010
3011 wxWinHashTable *wxWinHandleHash = NULL;
3012
3013 wxWindow* wxFindWinFromHandle(
3014 WXHWND hWnd
3015 )
3016 {
3017 return (wxWindow *)wxWinHandleHash->Get((long)hWnd);
3018 } // end of wxFindWinFromHandle
3019
3020 void wxAssociateWinWithHandle(
3021 HWND hWnd
3022 , wxWindowOS2* pWin
3023 )
3024 {
3025 //
3026 // Adding NULL hWnd is (first) surely a result of an error and
3027 // (secondly) breaks menu command processing
3028 //
3029 wxCHECK_RET( hWnd != (HWND)NULL,
3030 wxT("attempt to add a NULL hWnd to window list ignored") );
3031
3032
3033 wxWindow* pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
3034
3035 if (pOldWin && (pOldWin != pWin))
3036 {
3037 wxString str(pWin->GetClassInfo()->GetClassName());
3038 wxLogError( "Bug! Found existing HWND %X for new window of class %s"
3039 ,(int)hWnd
3040 ,(const char*)str
3041 );
3042 }
3043 else if (!pOldWin)
3044 {
3045 wxWinHandleHash->Put( (long)hWnd
3046 ,(wxWindow *)pWin
3047 );
3048 }
3049 } // end of wxAssociateWinWithHandle
3050
3051 void wxRemoveHandleAssociation(
3052 wxWindowOS2* pWin
3053 )
3054 {
3055 wxWinHandleHash->Delete((long)pWin->GetHWND());
3056 } // end of wxRemoveHandleAssociation
3057
3058 //
3059 // Default destroyer - override if you destroy it in some other way
3060 // (e.g. with MDI child windows)
3061 //
3062 void wxWindowOS2::OS2DestroyWindow()
3063 {
3064 }
3065
3066 bool wxWindowOS2::OS2GetCreateWindowCoords(
3067 const wxPoint& rPos
3068 , const wxSize& rSize
3069 , int& rnX
3070 , int& rnY
3071 , int& rnWidth
3072 , int& rnHeight
3073 ) const
3074 {
3075 bool bNonDefault = FALSE;
3076 static const int DEFAULT_Y = 200;
3077 static const int DEFAULT_H = 250;
3078
3079 if (rPos.x == -1)
3080 {
3081 rnX = rnY = CW_USEDEFAULT;
3082 }
3083 else
3084 {
3085 rnX = rPos.x;
3086 rnY = rPos.y == -1 ? DEFAULT_Y : rPos.y;
3087 bNonDefault = TRUE;
3088 }
3089 if (rSize.x == -1)
3090 {
3091 rnWidth = rnHeight = CW_USEDEFAULT;
3092 }
3093 else
3094 {
3095 rnWidth = rSize.x;
3096 rnHeight = rSize.y == -1 ? DEFAULT_H : rSize.y;
3097 bNonDefault = TRUE;
3098 }
3099 return bNonDefault;
3100 } // end of wxWindowOS2::OS2GetCreateWindowCoords
3101
3102 WXHWND wxWindowOS2::OS2GetParent() const
3103 {
3104 return m_parent ? m_parent->GetHWND() : NULL;
3105 }
3106
3107 bool wxWindowOS2::OS2Create(
3108 PSZ zClass
3109 , const char* zTitle
3110 , WXDWORD dwStyle
3111 , const wxPoint& rPos
3112 , const wxSize& rSize
3113 , void* pCtlData
3114 , WXDWORD dwExStyle
3115 , bool bIsChild
3116 )
3117 {
3118 ERRORID vError;
3119 wxString sError;
3120 int nX = 0L;
3121 int nY = 0L;
3122 int nWidth = 0L;
3123 int nHeight = 0L;
3124 long lControlId = 0L;
3125 wxWindowCreationHook vHook(this);
3126 wxString sClassName((wxChar*)zClass);
3127
3128 OS2GetCreateWindowCoords( rPos
3129 ,rSize
3130 ,nX
3131 ,nY
3132 ,nWidth
3133 ,nHeight
3134 );
3135
3136 if (bIsChild)
3137 {
3138 lControlId = GetId();
3139 if (GetWindowStyleFlag() & wxCLIP_SIBLINGS)
3140 {
3141 dwStyle |= WS_CLIPSIBLINGS;
3142 }
3143 }
3144 //
3145 // For each class "Foo" we have we also have "FooNR" ("no repaint") class
3146 // which is the same but without CS_[HV]REDRAW class styles so using it
3147 // ensures that the window is not fully repainted on each resize
3148 //
3149 if (!HasFlag(wxFULL_REPAINT_ON_RESIZE))
3150 {
3151 sClassName += wxT("NR");
3152 }
3153 m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
3154 ,(PSZ)sClassName.c_str()
3155 ,(PSZ)zTitle ? zTitle : ""
3156 ,(ULONG)dwStyle
3157 ,(LONG)0L
3158 ,(LONG)0L
3159 ,(LONG)0L
3160 ,(LONG)0L
3161 ,NULLHANDLE
3162 ,HWND_TOP
3163 ,(ULONG)lControlId
3164 ,pCtlData
3165 ,NULL
3166 );
3167 if (!m_hWnd)
3168 {
3169 vError = ::WinGetLastError(wxGetInstance());
3170 sError = wxPMErrorToStr(vError);
3171 return FALSE;
3172 }
3173 SubclassWin(m_hWnd);
3174 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
3175
3176 m_backgroundColour.Set(wxString("GREY"));
3177
3178 LONG lColor = (LONG)m_backgroundColour.GetPixel();
3179
3180 if (!::WinSetPresParam( m_hWnd
3181 ,PP_BACKGROUNDCOLOR
3182 ,sizeof(LONG)
3183 ,(PVOID)&lColor
3184 ))
3185 {
3186 vError = ::WinGetLastError(vHabmain);
3187 sError = wxPMErrorToStr(vError);
3188 wxLogError("Error creating frame. Error: %s\n", sError.c_str());
3189 return FALSE;
3190 }
3191 SetSize( nX
3192 ,nY
3193 ,nWidth
3194 ,nHeight
3195 );
3196 return TRUE;
3197 } // end of WinGuiBase_Window::OS2Create
3198
3199 // ===========================================================================
3200 // OS2 PM message handlers
3201 // ===========================================================================
3202
3203 // ---------------------------------------------------------------------------
3204 // window creation/destruction
3205 // ---------------------------------------------------------------------------
3206
3207 bool wxWindowOS2::HandleCreate(
3208 WXLPCREATESTRUCT WXUNUSED(vCs)
3209 , bool* pbMayCreate
3210 )
3211 {
3212 wxWindowCreateEvent vEvent((wxWindow*)this);
3213
3214 (void)GetEventHandler()->ProcessEvent(vEvent);
3215 *pbMayCreate = TRUE;
3216 return TRUE;
3217 } // end of wxWindowOS2::HandleCreate
3218
3219 bool wxWindowOS2::HandleDestroy()
3220 {
3221 wxWindowDestroyEvent vEvent((wxWindow*)this);
3222 vEvent.SetId(GetId());
3223 (void)GetEventHandler()->ProcessEvent(vEvent);
3224
3225 //
3226 // Delete our drop target if we've got one
3227 //
3228 #if wxUSE_DRAG_AND_DROP
3229 if (m_dropTarget != NULL)
3230 {
3231 delete m_dropTarget;
3232 m_dropTarget = NULL;
3233 }
3234 #endif // wxUSE_DRAG_AND_DROP
3235
3236 //
3237 // WM_DESTROY handled
3238 //
3239 return TRUE;
3240 } // end of wxWindowOS2::HandleDestroy
3241
3242 // ---------------------------------------------------------------------------
3243 // activation/focus
3244 // ---------------------------------------------------------------------------
3245 void wxWindowOS2::OnSetFocus(
3246 wxFocusEvent& rEvent
3247 )
3248 {
3249 rEvent.Skip();
3250 } // end of wxWindowOS2::OnSetFocus
3251
3252 bool wxWindowOS2::HandleActivate(
3253 int nState
3254 , WXHWND WXUNUSED(hActivate)
3255 )
3256 {
3257 wxActivateEvent vEvent( wxEVT_ACTIVATE
3258 ,(bool)nState
3259 ,m_windowId
3260 );
3261 vEvent.SetEventObject(this);
3262 return GetEventHandler()->ProcessEvent(vEvent);
3263 } // end of wxWindowOS2::HandleActivate
3264
3265 bool wxWindowOS2::HandleSetFocus(
3266 WXHWND WXUNUSED(hWnd)
3267 )
3268 {
3269 //
3270 // Notify the parent keeping track of focus for the kbd navigation
3271 // purposes that we got it
3272 //
3273 wxChildFocusEvent vEventFocus((wxWindow *)this);
3274 (void)GetEventHandler()->ProcessEvent(vEventFocus);
3275
3276 #if wxUSE_CARET
3277 //
3278 // Deal with caret
3279 //
3280 if (m_caret)
3281 {
3282 m_caret->OnSetFocus();
3283 }
3284 #endif // wxUSE_CARET
3285
3286 #if wxUSE_TEXTCTRL
3287 // If it's a wxTextCtrl don't send the event as it will be done
3288 // after the control gets to process it from EN_FOCUS handler
3289 if ( wxDynamicCastThis(wxTextCtrl) )
3290 {
3291 return FALSE;
3292 }
3293 #endif // wxUSE_TEXTCTRL
3294
3295 wxFocusEvent vEvent(wxEVT_SET_FOCUS, m_windowId);
3296
3297 vEvent.SetEventObject(this);
3298 return GetEventHandler()->ProcessEvent(vEvent);
3299 } // end of wxWindowOS2::HandleSetFocus
3300
3301 bool wxWindowOS2::HandleKillFocus(
3302 WXHWND hWnd
3303 )
3304 {
3305 #if wxUSE_CARET
3306 //
3307 // Deal with caret
3308 //
3309 if (m_caret)
3310 {
3311 m_caret->OnKillFocus();
3312 }
3313 #endif // wxUSE_CARET
3314
3315 #if wxUSE_TEXTCTRL
3316 //
3317 // If it's a wxTextCtrl don't send the event as it will be done
3318 // after the control gets to process it.
3319 //
3320 wxTextCtrl* pCtrl = wxDynamicCastThis(wxTextCtrl);
3321
3322 if (pCtrl)
3323 {
3324 return FALSE;
3325 }
3326 #endif
3327
3328 //
3329 // Don't send the event when in the process of being deleted. This can
3330 // only cause problems if the event handler tries to access the object.
3331 //
3332 if ( m_isBeingDeleted )
3333 {
3334 return FALSE;
3335 }
3336
3337 wxFocusEvent vEvent( wxEVT_KILL_FOCUS
3338 ,m_windowId
3339 );
3340
3341 vEvent.SetEventObject(this);
3342
3343 //
3344 // wxFindWinFromHandle() may return NULL, it is ok
3345 //
3346 vEvent.SetWindow(wxFindWinFromHandle(hWnd));
3347 return GetEventHandler()->ProcessEvent(vEvent);
3348 } // end of wxWindowOS2::HandleKillFocus
3349
3350 // ---------------------------------------------------------------------------
3351 // miscellaneous
3352 // ---------------------------------------------------------------------------
3353
3354 bool wxWindowOS2::HandleShow(
3355 bool bShow
3356 , int WXUNUSED(nStatus)
3357 )
3358 {
3359 wxShowEvent vEvent(GetId(), bShow);
3360
3361 vEvent.m_eventObject = this;
3362 return GetEventHandler()->ProcessEvent(vEvent);
3363 } // end of wxWindowOS2::HandleShow
3364
3365 bool wxWindowOS2::HandleInitDialog(
3366 WXHWND WXUNUSED(hWndFocus)
3367 )
3368 {
3369 wxInitDialogEvent vEvent(GetId());
3370
3371 vEvent.m_eventObject = this;
3372 return GetEventHandler()->ProcessEvent(vEvent);
3373 } // end of wxWindowOS2::HandleInitDialog
3374
3375 bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
3376 {
3377 // TODO: We'll handle drag and drop later
3378 return FALSE;
3379 }
3380
3381 bool wxWindowOS2::HandleSetCursor(
3382 USHORT WXUNUSED(vId)
3383 , WXHWND hPointer
3384 )
3385 {
3386 //
3387 // Under OS/2 PM this allows the pointer to be changed
3388 // as it passes over a control
3389 //
3390 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)hPointer);
3391 return TRUE;
3392 } // end of wxWindowOS2::HandleSetCursor
3393
3394 // ---------------------------------------------------------------------------
3395 // owner drawn stuff
3396 // ---------------------------------------------------------------------------
3397 bool wxWindowOS2::OS2OnDrawItem(
3398 int vId
3399 , WXDRAWITEMSTRUCT* pItemStruct
3400 )
3401 {
3402 #if wxUSE_OWNER_DRAWN
3403 wxDC vDc;
3404
3405 #if wxUSE_MENUS_NATIVE
3406 //
3407 // Is it a menu item?
3408 //
3409 if (vId == 0)
3410 {
3411 ERRORID vError;
3412 wxString sError;
3413 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
3414 wxFrame* pFrame = (wxFrame*)this;
3415 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
3416 HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
3417 wxRect vRect( pMeasureStruct->rclItem.xLeft
3418 ,pMeasureStruct->rclItem.yBottom
3419 ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
3420 ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
3421 );
3422 vDc.SetHDC( hDC
3423 ,FALSE
3424 );
3425 vDc.SetHPS(pMeasureStruct->hps);
3426 //
3427 // Load the wxWidgets Pallete and set to RGB mode
3428 //
3429 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3430 ,0L
3431 ,LCOLF_CONSECRGB
3432 ,0L
3433 ,(LONG)wxTheColourDatabase->m_nSize
3434 ,(PLONG)wxTheColourDatabase->m_palTable
3435 ))
3436 {
3437 vError = ::WinGetLastError(vHabmain);
3438 sError = wxPMErrorToStr(vError);
3439 wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
3440 }
3441 //
3442 // Set the color table to RGB mode
3443 //
3444 if (!::GpiCreateLogColorTable( pMeasureStruct->hps
3445 ,0L
3446 ,LCOLF_RGB
3447 ,0L
3448 ,0L
3449 ,NULL
3450 ))
3451 {
3452 vError = ::WinGetLastError(vHabmain);
3453 sError = wxPMErrorToStr(vError);
3454 wxLogError("Unable to set current color table. Error: %s\n", sError.c_str());
3455 }
3456
3457 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3458
3459
3460 int eAction = 0;
3461 int eStatus = 0;
3462
3463 if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
3464 {
3465 //
3466 // Entire Item needs to be redrawn (either it has reappeared from
3467 // behind another window or is being displayed for the first time
3468 //
3469 eAction = wxOwnerDrawn::wxODDrawAll;
3470
3471 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3472 {
3473 //
3474 // If it is currently selected we let the system handle it
3475 //
3476 eStatus |= wxOwnerDrawn::wxODSelected;
3477 }
3478 if (pMeasureStruct->fsAttribute & MIA_CHECKED)
3479 {
3480 //
3481 // If it is currently checked we draw our own
3482 //
3483 eStatus |= wxOwnerDrawn::wxODChecked;
3484 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_CHECKED;
3485 }
3486 if (pMeasureStruct->fsAttribute & MIA_DISABLED)
3487 {
3488 //
3489 // If it is currently disabled we let the system handle it
3490 //
3491 eStatus |= wxOwnerDrawn::wxODDisabled;
3492 }
3493 //
3494 // Don't really care about framed (indicationg focus) or NoDismiss
3495 //
3496 }
3497 else
3498 {
3499 if (pMeasureStruct->fsAttribute & MIA_HILITED)
3500 {
3501 eAction = wxOwnerDrawn::wxODDrawAll;
3502 eStatus |= wxOwnerDrawn::wxODSelected;
3503 //
3504 // Keep the system from trying to highlight with its bogus colors
3505 //
3506 pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
3507 }
3508 else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
3509 {
3510 eAction = wxOwnerDrawn::wxODDrawAll;
3511 eStatus = 0;
3512 //
3513 // Keep the system from trying to highlight with its bogus colors
3514 //
3515 pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
3516 }
3517 else
3518 {
3519 //
3520 // For now we don't care about anything else
3521 // just ignore the entire message!
3522 //
3523 return TRUE;
3524 }
3525 }
3526 //
3527 // Now redraw the item
3528 //
3529 return(pMenuItem->OnDrawItem( vDc
3530 ,vRect
3531 ,(wxOwnerDrawn::wxODAction)eAction
3532 ,(wxOwnerDrawn::wxODStatus)eStatus
3533 ));
3534 //
3535 // leave the fsAttribute and fsOldAttribute unchanged. If different,
3536 // the system will do the highlight or fraeming or disabling for us,
3537 // otherwise, we'd have to do it ourselves.
3538 //
3539 }
3540 #endif // wxUSE_MENUS_NATIVE
3541
3542 wxWindow* pItem = FindItem(vId);
3543
3544 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3545 {
3546 return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
3547 }
3548 #else
3549 vId = vId;
3550 pItemStruct = pItemStruct;
3551 #endif
3552 return FALSE;
3553 } // end of wxWindowOS2::OS2OnDrawItem
3554
3555 long wxWindowOS2::OS2OnMeasureItem(
3556 int lId
3557 , WXMEASUREITEMSTRUCT* pItemStruct
3558 )
3559 {
3560 #if wxUSE_OWNER_DRAWN
3561 //
3562 // Is it a menu item?
3563 //
3564 if (lId == 65536) // I really don't like this...has to be a better indicator
3565 {
3566 if (IsKindOf(CLASSINFO(wxFrame))) // we'll assume if Frame then a menu
3567 {
3568 size_t nWidth;
3569 size_t nHeight;
3570 POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
3571 wxFrame* pFrame = (wxFrame*)this;
3572 wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
3573
3574 wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
3575 nWidth = 0L;
3576 nHeight = 0L;
3577 if (pMenuItem->OnMeasureItem( &nWidth
3578 ,&nHeight
3579 ))
3580 {
3581 MRESULT mRc;
3582
3583 pMeasureStruct->rclItem.xRight = nWidth;
3584 pMeasureStruct->rclItem.xLeft = 0L;
3585 pMeasureStruct->rclItem.yTop = nHeight;
3586 pMeasureStruct->rclItem.yBottom = 0L;
3587 mRc = MRFROM2SHORT(nHeight, nWidth);
3588 return LONGFROMMR(mRc);
3589 }
3590 return 0L;
3591 }
3592 }
3593 wxWindow* pItem = FindItem(lId);
3594
3595 if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
3596 {
3597 OWNERITEM vItem;
3598
3599 vItem.idItem = (LONG)pItemStruct;
3600 return ((wxControl *)pItem)->OS2OnMeasure((WXMEASUREITEMSTRUCT*)&vItem);
3601 }
3602 #else
3603 lId = lId;
3604 pItemStruct = pItemStruct;
3605 #endif // wxUSE_OWNER_DRAWN
3606 return FALSE;
3607 }
3608
3609 // ---------------------------------------------------------------------------
3610 // colours and palettes
3611 // ---------------------------------------------------------------------------
3612
3613 bool wxWindowOS2::HandleSysColorChange()
3614 {
3615 wxSysColourChangedEvent vEvent;
3616
3617 vEvent.SetEventObject(this);
3618 return GetEventHandler()->ProcessEvent(vEvent);
3619 } // end of wxWindowOS2::HandleSysColorChange
3620
3621 bool wxWindowOS2::HandleCtlColor(
3622 WXHBRUSH* WXUNUSED(phBrush)
3623 )
3624 {
3625 //
3626 // Not much provided with message. So not sure I can do anything with it
3627 //
3628 return TRUE;
3629 } // end of wxWindowOS2::HandleCtlColor
3630
3631
3632 // Define for each class of dialog and control
3633 WXHBRUSH wxWindowOS2::OnCtlColor(WXHDC WXUNUSED(hDC),
3634 WXHWND WXUNUSED(hWnd),
3635 WXUINT WXUNUSED(nCtlColor),
3636 WXUINT WXUNUSED(message),
3637 WXWPARAM WXUNUSED(wParam),
3638 WXLPARAM WXUNUSED(lParam))
3639 {
3640 return (WXHBRUSH)0;
3641 }
3642
3643 bool wxWindowOS2::HandlePaletteChanged()
3644 {
3645 // need to set this to something first
3646 WXHWND hWndPalChange = NULLHANDLE;
3647
3648 wxPaletteChangedEvent vEvent(GetId());
3649
3650 vEvent.SetEventObject(this);
3651 vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
3652
3653 return GetEventHandler()->ProcessEvent(vEvent);
3654 } // end of wxWindowOS2::HandlePaletteChanged
3655
3656 //
3657 // Responds to colour changes: passes event on to children.
3658 //
3659 void wxWindowOS2::OnSysColourChanged(
3660 wxSysColourChangedEvent& rEvent
3661 )
3662 {
3663 wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
3664
3665 while (node)
3666 {
3667 //
3668 // Only propagate to non-top-level windows
3669 //
3670 wxWindow* pWin = (wxWindow *)node->GetData();
3671
3672 if (pWin->GetParent())
3673 {
3674 wxSysColourChangedEvent vEvent;
3675
3676 rEvent.m_eventObject = pWin;
3677 pWin->GetEventHandler()->ProcessEvent(vEvent);
3678 }
3679 node = node->GetNext();
3680 }
3681 } // end of wxWindowOS2::OnSysColourChanged
3682
3683 // ---------------------------------------------------------------------------
3684 // painting
3685 // ---------------------------------------------------------------------------
3686
3687 void wxWindow::OnPaint (
3688 wxPaintEvent& rEvent
3689 )
3690 {
3691 HDC hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
3692
3693 if (hDC != 0)
3694 {
3695 OS2DefWindowProc( (WXUINT)WM_PAINT
3696 ,(WXWPARAM)hDC
3697 ,(WXLPARAM)0
3698 );
3699 }
3700 } // end of wxWindow::OnPaint
3701
3702 bool wxWindowOS2::HandlePaint()
3703 {
3704 HRGN hRgn;
3705 wxPaintEvent vEvent(m_windowId);
3706 HPS hPS;
3707 bool bProcessed;
3708
3709 // Create empty region
3710 // TODO: get HPS somewhere else if possible
3711 hPS = ::WinGetPS(GetHwnd());
3712 hRgn = ::GpiCreateRegion(hPS, 0, NULL);
3713
3714 if (::WinQueryUpdateRegion(GetHwnd(), hRgn) == RGN_ERROR)
3715 {
3716 wxLogLastError("CreateRectRgn");
3717 return FALSE;
3718 }
3719
3720 // Get all the rectangles from the region, convert the individual
3721 // rectangles to "the other" coordinate system and reassemble a
3722 // region from the rectangles, to be feed into m_updateRegion.
3723 //
3724 // FIXME: This is a bad hack since OS/2 API specifies that rectangles
3725 // passed into GpiSetRegion must not have Bottom > Top,
3726 // however, at first sight, it _seems_ to work nonetheless.
3727 //
3728 RGNRECT vRgnData;
3729 PRECTL pUpdateRects = NULL;
3730 vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
3731 if (::GpiQueryRegionRects( hPS // Pres space
3732 ,hRgn // Handle of region to query
3733 ,NULL // Return all RECTs
3734 ,&vRgnData // Will contain number or RECTs in region
3735 ,NULL // NULL to return number of RECTs
3736 ))
3737 {
3738 pUpdateRects = new RECTL[vRgnData.crcReturned];
3739 vRgnData.crc = vRgnData.crcReturned;
3740 vRgnData.ircStart = 1;
3741 if (::GpiQueryRegionRects( hPS // Pres space of source
3742 ,hRgn // Handle of source region
3743 ,NULL // Return all RECTs
3744 ,&vRgnData // Operations set to return rects
3745 ,pUpdateRects // Will contain the actual RECTS
3746 ))
3747 {
3748 int height;
3749 RECT vRect;
3750 ::WinQueryWindowRect(GetHwnd(), &vRect);
3751 height = vRect.yTop;
3752
3753 for(size_t i = 0; i < vRgnData.crc; i++)
3754 {
3755 int rectHeight;
3756 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
3757 pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
3758 pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
3759 }
3760 ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
3761 delete [] pUpdateRects;
3762 }
3763 }
3764
3765 m_updateRegion = wxRegion(hRgn, hPS);
3766
3767 vEvent.SetEventObject(this);
3768 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
3769
3770 if (!bProcessed &&
3771 IsKindOf(CLASSINFO(wxPanel)) &&
3772 GetChildren().GetCount() == 0
3773 )
3774 {
3775 //
3776 // OS/2 needs to process this right here, not by the default proc
3777 // Window's default proc correctly paints everything, OS/2 does not.
3778 // For decorative panels that typically have no children, we draw
3779 // borders.
3780 //
3781 HPS hPS;
3782 RECTL vRect;
3783
3784 hPS = ::WinBeginPaint( GetHwnd()
3785 ,NULLHANDLE
3786 ,&vRect
3787 );
3788 if(hPS)
3789 {
3790 ::GpiCreateLogColorTable( hPS
3791 ,0L
3792 ,LCOLF_CONSECRGB
3793 ,0L
3794 ,(LONG)wxTheColourDatabase->m_nSize
3795 ,(PLONG)wxTheColourDatabase->m_palTable
3796 );
3797 ::GpiCreateLogColorTable( hPS
3798 ,0L
3799 ,LCOLF_RGB
3800 ,0L
3801 ,0L
3802 ,NULL
3803 );
3804 if (::WinIsWindowVisible(GetHWND()))
3805 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3806 if (m_dwExStyle)
3807 {
3808 LINEBUNDLE vLineBundle;
3809
3810 vLineBundle.lColor = 0x00000000; // Black
3811 vLineBundle.usMixMode = FM_OVERPAINT;
3812 vLineBundle.fxWidth = 1;
3813 vLineBundle.lGeomWidth = 1;
3814 vLineBundle.usType = LINETYPE_SOLID;
3815 vLineBundle.usEnd = 0;
3816 vLineBundle.usJoin = 0;
3817 ::GpiSetAttrs( hPS
3818 ,PRIM_LINE
3819 ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
3820 ,0L
3821 ,&vLineBundle
3822 );
3823 ::WinQueryWindowRect(GetHwnd(), &vRect);
3824 wxDrawBorder( hPS
3825 ,vRect
3826 ,m_dwExStyle
3827 );
3828 }
3829 }
3830 ::WinEndPaint(hPS);
3831 bProcessed = TRUE;
3832 }
3833 else if (!bProcessed &&
3834 IsKindOf(CLASSINFO(wxPanel))
3835 )
3836 {
3837 //
3838 // Panel with children, usually fills a frame client so no borders.
3839 //
3840 HPS hPS;
3841 RECTL vRect;
3842
3843 hPS = ::WinBeginPaint( GetHwnd()
3844 ,NULLHANDLE
3845 ,&vRect
3846 );
3847 if(hPS)
3848 {
3849 ::GpiCreateLogColorTable( hPS
3850 ,0L
3851 ,LCOLF_CONSECRGB
3852 ,0L
3853 ,(LONG)wxTheColourDatabase->m_nSize
3854 ,(PLONG)wxTheColourDatabase->m_palTable
3855 );
3856 ::GpiCreateLogColorTable( hPS
3857 ,0L
3858 ,LCOLF_RGB
3859 ,0L
3860 ,0L
3861 ,NULL
3862 );
3863
3864 if (::WinIsWindowVisible(GetHWND()))
3865 ::WinFillRect(hPS, &vRect, GetBackgroundColour().GetPixel());
3866 }
3867 ::WinEndPaint(hPS);
3868 bProcessed = TRUE;
3869 }
3870 return bProcessed;
3871 } // end of wxWindowOS2::HandlePaint
3872
3873 bool wxWindowOS2::HandleEraseBkgnd(
3874 WXHDC hDC
3875 )
3876 {
3877 SWP vSwp;
3878 bool rc;
3879
3880 ::WinQueryWindowPos(GetHwnd(), &vSwp);
3881 if (vSwp.fl & SWP_MINIMIZE)
3882 return TRUE;
3883
3884 wxDC vDC;
3885
3886 vDC.m_hPS = (HPS)hDC; // this is really a PS
3887 vDC.SetWindow((wxWindow*)this);
3888 vDC.BeginDrawing();
3889
3890 wxEraseEvent vEvent(m_windowId, &vDC);
3891
3892 vEvent.SetEventObject(this);
3893
3894 rc = GetEventHandler()->ProcessEvent(vEvent);
3895
3896 vDC.EndDrawing();
3897 vDC.m_hPS = NULLHANDLE;
3898 return TRUE;
3899 } // end of wxWindowOS2::HandleEraseBkgnd
3900
3901 void wxWindowOS2::OnEraseBackground(
3902 wxEraseEvent& rEvent
3903 )
3904 {
3905 RECTL vRect;
3906 HPS hPS = rEvent.m_dc->m_hPS;
3907 APIRET rc;
3908 LONG lColor = m_backgroundColour.GetPixel();
3909
3910 rc = ::WinQueryWindowRect(GetHwnd(), &vRect);
3911 rc = ::WinFillRect(hPS, &vRect, lColor);
3912 } // end of wxWindowOS2::OnEraseBackground
3913
3914 // ---------------------------------------------------------------------------
3915 // moving and resizing
3916 // ---------------------------------------------------------------------------
3917
3918 bool wxWindowOS2::HandleMinimize()
3919 {
3920 wxIconizeEvent vEvent(m_windowId);
3921
3922 vEvent.SetEventObject(this);
3923 return GetEventHandler()->ProcessEvent(vEvent);
3924 } // end of wxWindowOS2::HandleMinimize
3925
3926 bool wxWindowOS2::HandleMaximize()
3927 {
3928 wxMaximizeEvent vEvent(m_windowId);
3929
3930 vEvent.SetEventObject(this);
3931 return GetEventHandler()->ProcessEvent(vEvent);
3932 } // end of wxWindowOS2::HandleMaximize
3933
3934 bool wxWindowOS2::HandleMove(
3935 int nX
3936 , int nY
3937 )
3938 {
3939 wxMoveEvent vEvent(wxPoint(nX, nY), m_windowId);
3940
3941 vEvent.SetEventObject(this);
3942 return GetEventHandler()->ProcessEvent(vEvent);
3943 } // end of wxWindowOS2::HandleMove
3944
3945 bool wxWindowOS2::HandleSize(
3946 int nWidth
3947 , int nHeight
3948 , WXUINT WXUNUSED(nFlag)
3949 )
3950 {
3951 wxSizeEvent vEvent(wxSize(nWidth, nHeight), m_windowId);
3952
3953 vEvent.SetEventObject(this);
3954 return GetEventHandler()->ProcessEvent(vEvent);
3955 } // end of wxWindowOS2::HandleSize
3956
3957 bool wxWindowOS2::HandleGetMinMaxInfo(
3958 PSWP pSwp
3959 )
3960 {
3961 POINTL vPoint;
3962
3963 switch(pSwp->fl)
3964 {
3965 case SWP_MAXIMIZE:
3966 ::WinGetMaxPosition(GetHwnd(), pSwp);
3967 m_maxWidth = pSwp->cx;
3968 m_maxHeight = pSwp->cy;
3969 break;
3970
3971 case SWP_MINIMIZE:
3972 ::WinGetMinPosition(GetHwnd(), pSwp, &vPoint);
3973 m_minWidth = pSwp->cx;
3974 m_minHeight = pSwp->cy;
3975 break;
3976
3977 default:
3978 return FALSE;
3979 }
3980 return TRUE;
3981 } // end of wxWindowOS2::HandleGetMinMaxInfo
3982
3983 // ---------------------------------------------------------------------------
3984 // command messages
3985 // ---------------------------------------------------------------------------
3986 bool wxWindowOS2::HandleCommand(
3987 WXWORD wId
3988 , WXWORD wCmd
3989 , WXHWND hControl
3990 )
3991 {
3992 #if wxUSE_MENUS_NATIVE
3993 if (wxCurrentPopupMenu)
3994 {
3995 wxMenu* pPopupMenu = wxCurrentPopupMenu;
3996
3997 wxCurrentPopupMenu = NULL;
3998 return pPopupMenu->OS2Command(wCmd, wId);
3999 }
4000 #endif // wxUSE_MENUS_NATIVE
4001
4002 wxWindow* pWin = FindItem(wId);
4003
4004 if (!pWin)
4005 {
4006 pWin = wxFindWinFromHandle(hControl);
4007 }
4008
4009 if (pWin)
4010 return pWin->OS2Command(wCmd, wId);
4011
4012 return FALSE;
4013 } // end of wxWindowOS2::HandleCommand
4014
4015 bool wxWindowOS2::HandleSysCommand(
4016 WXWPARAM wParam
4017 , WXLPARAM WXUNUSED(lParam)
4018 )
4019 {
4020 //
4021 // 4 bits are reserved
4022 //
4023 switch (SHORT1FROMMP(wParam))
4024 {
4025 case SC_MAXIMIZE:
4026 return HandleMaximize();
4027
4028 case SC_MINIMIZE:
4029 return HandleMinimize();
4030 }
4031 return FALSE;
4032 } // end of wxWindowOS2::HandleSysCommand
4033
4034 // ---------------------------------------------------------------------------
4035 // mouse events
4036 // ---------------------------------------------------------------------------
4037 //TODO!!! check against MSW
4038 void wxWindowOS2::InitMouseEvent(
4039 wxMouseEvent& rEvent
4040 , int nX
4041 , int nY
4042 , WXUINT uFlags
4043 )
4044 {
4045 int nHeight;
4046 DoGetSize(0, &nHeight);
4047 rEvent.m_x = nX;
4048 // Convert to wxWidgets standard coordinate system!
4049 rEvent.m_y = nHeight - nY;
4050 rEvent.m_shiftDown = ((uFlags & KC_SHIFT) != 0);
4051 rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
4052 rEvent.m_altDown = ((uFlags & KC_ALT) != 0);
4053 rEvent.m_leftDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
4054 0x8000) != 0;
4055 rEvent.m_middleDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
4056 0x8000) != 0;
4057 rEvent.m_rightDown = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
4058 0x8000) != 0;
4059 rEvent.SetTimestamp(s_currentMsg.time);
4060 rEvent.m_eventObject = this;
4061 rEvent.SetId(GetId());
4062
4063 #if wxUSE_MOUSEEVENT_HACK
4064 m_lastMouseX = nX;
4065 m_lastMouseY = nY;
4066 m_lastMouseEvent = rEvent.GetEventType();
4067 #endif // wxUSE_MOUSEEVENT_HACK
4068 } // end of wxWindowOS2::InitMouseEvent
4069
4070 bool wxWindowOS2::HandleMouseEvent(
4071 WXUINT uMsg
4072 , int nX
4073 , int nY
4074 , WXUINT uFlags
4075 )
4076 {
4077 bool bProcessed = FALSE;
4078
4079 //
4080 // The mouse events take consecutive IDs from WM_MOUSEFIRST to
4081 // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
4082 // from the message id and take the value in the table to get wxWin event
4083 // id
4084 //
4085 static const wxEventType eventsMouse[] =
4086 {
4087 wxEVT_MOTION,
4088 wxEVT_LEFT_DOWN,
4089 wxEVT_LEFT_UP,
4090 wxEVT_LEFT_DCLICK,
4091 wxEVT_RIGHT_DOWN,
4092 wxEVT_RIGHT_UP,
4093 wxEVT_RIGHT_DCLICK,
4094 wxEVT_MIDDLE_DOWN,
4095 wxEVT_MIDDLE_UP,
4096 wxEVT_MIDDLE_DCLICK
4097 };
4098
4099 // Bounds check
4100 if ((uMsg >= WM_MOUSEMOVE) && (uMsg <= WM_BUTTON3DBLCLK))
4101 {
4102 wxMouseEvent vEvent(eventsMouse[uMsg - WM_MOUSEMOVE]);
4103
4104 InitMouseEvent( vEvent
4105 ,nX
4106 ,nY
4107 ,uFlags
4108 );
4109
4110 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
4111 if (!bProcessed)
4112 {
4113 HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
4114
4115 if (hCursor != NULLHANDLE)
4116 {
4117 ::WinSetPointer(HWND_DESKTOP, hCursor);
4118 bProcessed = TRUE;
4119 }
4120 }
4121 }
4122 return bProcessed;
4123 } // end of wxWindowOS2::HandleMouseEvent
4124
4125 bool wxWindowOS2::HandleMouseMove(
4126 int nX
4127 , int nY
4128 , WXUINT uFlags
4129 )
4130 {
4131 if (!m_bMouseInWindow)
4132 {
4133 //
4134 // Generate an ENTER event
4135 //
4136 m_bMouseInWindow = TRUE;
4137
4138 wxMouseEvent vEvent(wxEVT_ENTER_WINDOW);
4139
4140 InitMouseEvent( vEvent
4141 ,nX
4142 ,nY
4143 ,uFlags
4144 );
4145
4146 (void)GetEventHandler()->ProcessEvent(vEvent);
4147 }
4148 return HandleMouseEvent( WM_MOUSEMOVE
4149 ,nX
4150 ,nY
4151 ,uFlags
4152 );
4153 } // end of wxWindowOS2::HandleMouseMove
4154
4155 // ---------------------------------------------------------------------------
4156 // keyboard handling
4157 // ---------------------------------------------------------------------------
4158
4159 //
4160 // Create the key event of the given type for the given key - used by
4161 // HandleChar and HandleKeyDown/Up
4162 //
4163 wxKeyEvent wxWindowOS2::CreateKeyEvent(
4164 wxEventType eType
4165 , int nId
4166 , WXLPARAM lParam
4167 , WXWPARAM wParam
4168 ) const
4169 {
4170 wxKeyEvent vEvent(eType);
4171
4172 vEvent.SetId(GetId());
4173 vEvent.m_shiftDown = IsShiftDown();
4174 vEvent.m_controlDown = IsCtrlDown();
4175 vEvent.m_altDown = (HIWORD(lParam) & KC_ALT) == KC_ALT;
4176
4177 vEvent.m_eventObject = (wxWindow *)this; // const_cast
4178 vEvent.m_keyCode = nId;
4179 vEvent.m_rawCode = (wxUint32)wParam;
4180 vEvent.m_rawFlags = (wxUint32)lParam;
4181 vEvent.SetTimestamp(s_currentMsg.time);
4182
4183 //
4184 // Translate the position to client coords
4185 //
4186 POINTL vPoint;
4187 RECTL vRect;
4188
4189 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
4190 ::WinQueryWindowRect( GetHwnd()
4191 ,&vRect
4192 );
4193
4194 vPoint.x -= vRect.xLeft;
4195 vPoint.y -= vRect.yBottom;
4196
4197 vEvent.m_x = vPoint.x;
4198 vEvent.m_y = vPoint.y;
4199
4200 return vEvent;
4201 } // end of wxWindowOS2::CreateKeyEvent
4202
4203 //
4204 // isASCII is TRUE only when we're called from WM_CHAR handler and not from
4205 // WM_KEYDOWN one
4206 //
4207 bool wxWindowOS2::HandleChar(
4208 WXWPARAM wParam
4209 , WXLPARAM lParam
4210 , bool isASCII
4211 )
4212 {
4213 bool bCtrlDown = FALSE;
4214 int vId;
4215
4216 if (m_bLastKeydownProcessed)
4217 {
4218 //
4219 // The key was handled in the EVT_KEY_DOWN. Handling a key in an
4220 // EVT_KEY_DOWN handler is meant, by design, to prevent EVT_CHARs
4221 // from happening, so just bail out at this point.
4222 //
4223 m_bLastKeydownProcessed = FALSE;
4224 return TRUE;
4225 }
4226 if (isASCII)
4227 {
4228 //
4229 // If 1 -> 26, translate to either special keycode or just set
4230 // ctrlDown. IOW, Ctrl-C should result in keycode == 3 and
4231 // ControlDown() == TRUE.
4232 //
4233 vId = SHORT1FROMMP(lParam);
4234 if ((vId > 0) && (vId < 27))
4235 {
4236 switch (vId)
4237 {
4238 case 13:
4239 vId = WXK_RETURN;
4240 break;
4241
4242 case 8:
4243 vId = WXK_BACK;
4244 break;
4245
4246 case 9:
4247 vId = WXK_TAB;
4248 break;
4249
4250 default:
4251 bCtrlDown = TRUE;
4252 break;
4253 }
4254 }
4255 }
4256 else // we're called from WM_KEYDOWN
4257 {
4258 vId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4259 if (vId == 0)
4260 return FALSE;
4261 }
4262
4263 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_CHAR
4264 ,vId
4265 ,lParam
4266 ));
4267
4268 if (bCtrlDown)
4269 {
4270 vEvent.m_controlDown = TRUE;
4271 }
4272 return (GetEventHandler()->ProcessEvent(vEvent));
4273 }
4274
4275 bool wxWindowOS2::HandleKeyDown(
4276 WXWPARAM wParam
4277 , WXLPARAM lParam
4278 )
4279 {
4280 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4281
4282 if (!nId)
4283 {
4284 //
4285 // Normal ASCII char
4286 //
4287 nId = SHORT1FROMMP(lParam);
4288 }
4289
4290 if (nId != -1)
4291 {
4292 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_DOWN
4293 ,nId
4294 ,(MPARAM)lParam
4295 ,(MPARAM)wParam
4296 ));
4297
4298 if (GetEventHandler()->ProcessEvent(vEvent))
4299 {
4300 return TRUE;
4301 }
4302 }
4303 return FALSE;
4304 } // end of wxWindowOS2::HandleKeyDown
4305
4306 bool wxWindowOS2::HandleKeyUp(
4307 WXWPARAM wParam
4308 , WXLPARAM lParam
4309 )
4310 {
4311 int nId = wxCharCodeOS2ToWX((int)SHORT2FROMMP(lParam));
4312
4313 if (!nId)
4314 {
4315 //
4316 // Normal ASCII char
4317 //
4318 nId = (int)wParam;
4319 }
4320
4321 if (nId != -1)
4322 {
4323 wxKeyEvent vEvent(CreateKeyEvent( wxEVT_KEY_UP
4324 ,nId
4325 ,lParam
4326 ,wParam
4327 ));
4328
4329 if (GetEventHandler()->ProcessEvent(vEvent))
4330 return TRUE;
4331 }
4332 return FALSE;
4333 } // end of wxWindowOS2::HandleKeyUp
4334
4335 // ---------------------------------------------------------------------------
4336 // joystick
4337 // ---------------------------------------------------------------------------
4338
4339 // ---------------------------------------------------------------------------
4340 // scrolling
4341 // ---------------------------------------------------------------------------
4342
4343 bool wxWindowOS2::OS2OnScroll(
4344 int nOrientation
4345 , WXWORD wParam
4346 , WXWORD wPos
4347 , WXHWND hControl
4348 )
4349 {
4350 if (hControl)
4351 {
4352 wxWindow* pChild = wxFindWinFromHandle(hControl);
4353
4354 if (pChild )
4355 return pChild->OS2OnScroll( nOrientation
4356 ,wParam
4357 ,wPos
4358 ,hControl
4359 );
4360 }
4361
4362 wxScrollWinEvent vEvent;
4363
4364 vEvent.SetPosition(wPos);
4365 vEvent.SetOrientation(nOrientation);
4366 vEvent.m_eventObject = this;
4367
4368 switch (wParam)
4369 {
4370 case SB_LINEUP:
4371 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
4372 break;
4373
4374 case SB_LINEDOWN:
4375 vEvent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
4376 break;
4377
4378 case SB_PAGEUP:
4379 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
4380 break;
4381
4382 case SB_PAGEDOWN:
4383 vEvent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
4384 break;
4385
4386 case SB_SLIDERPOSITION:
4387 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
4388 break;
4389
4390 case SB_SLIDERTRACK:
4391 vEvent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
4392 break;
4393
4394 default:
4395 return FALSE;
4396 }
4397 return GetEventHandler()->ProcessEvent(vEvent);
4398 } // end of wxWindowOS2::OS2OnScroll
4399
4400 void wxWindowOS2::MoveChildren(
4401 int nDiff
4402 )
4403 {
4404 //
4405 // We want to handle top levels ourself, manually
4406 //
4407 if (!IsTopLevel() && GetAutoLayout())
4408 {
4409 Layout();
4410 }
4411 else
4412 {
4413 SWP vSwp;
4414
4415 for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
4416 node;
4417 node = node->GetNext())
4418 {
4419 wxWindow* pWin = node->GetData();
4420
4421 ::WinQueryWindowPos( GetHwndOf(pWin)
4422 ,&vSwp
4423 );
4424 if (pWin->IsKindOf(CLASSINFO(wxControl)))
4425 {
4426 wxControl* pCtrl;
4427
4428 //
4429 // Must deal with controls that have margins like ENTRYFIELD. The SWP
4430 // struct of such a control will have and origin offset from its intended
4431 // position by the width of the margins.
4432 //
4433 pCtrl = wxDynamicCast(pWin, wxControl);
4434 vSwp.y -= pCtrl->GetYComp();
4435 vSwp.x -= pCtrl->GetXComp();
4436 }
4437 ::WinSetWindowPos( GetHwndOf(pWin)
4438 ,HWND_TOP
4439 ,vSwp.x
4440 ,vSwp.y - nDiff
4441 ,vSwp.cx
4442 ,vSwp.cy
4443 ,SWP_MOVE
4444 );
4445 ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
4446 if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
4447 {
4448 wxRadioBox* pRadioBox;
4449
4450 pRadioBox = wxDynamicCast(pWin, wxRadioBox);
4451 pRadioBox->AdjustButtons( (int)vSwp.x
4452 ,(int)vSwp.y - nDiff
4453 ,(int)vSwp.cx
4454 ,(int)vSwp.cy
4455 ,pRadioBox->GetSizeFlags()
4456 );
4457 }
4458 if (pWin->IsKindOf(CLASSINFO(wxSlider)))
4459 {
4460 wxSlider* pSlider;
4461
4462 pSlider = wxDynamicCast(pWin, wxSlider);
4463 pSlider->AdjustSubControls( (int)vSwp.x
4464 ,(int)vSwp.y - nDiff
4465 ,(int)vSwp.cx
4466 ,(int)vSwp.cy
4467 ,(int)pSlider->GetSizeFlags()
4468 );
4469 }
4470 }
4471 }
4472 Refresh();
4473 } // end of wxWindowOS2::MoveChildren
4474
4475 //
4476 // Getting the Y position for a window, like a control, is a real
4477 // pain. There are three sitatuions we must deal with in determining
4478 // the OS2 to wxWidgets Y coordinate.
4479 //
4480 // 1) The controls are created in a dialog.
4481 // This is the easiest since a dialog is created with its original
4482 // size so the standard: Y = ParentHeight - (Y + ControlHeight);
4483 //
4484 // 2) The controls are direct children of a frame
4485 // In this instance the controls are actually children of the Frame's
4486 // client. During creation the frame's client resizes several times
4487 // during creation of the status bar and toolbars. The CFrame class
4488 // will take care of this using its AlterChildPos proc.
4489 //
4490 // 3) The controls are children of a panel, which in turn is a child of
4491 // a frame.
4492 // The panel may be one of many, in which case the same treatment
4493 // as 1 applies. It may be the only child, though.
4494 // This is the nastiest case. A panel is created as the only child of
4495 // the frame and as such, when a frame has only one child, the child is
4496 // expanded to fit the entire client area of the frame. Because the
4497 // controls are created BEFORE this occurs their positions are totally
4498 // whacked and any call to WinQueryWindowPos will return invalid
4499 // coordinates. So for this situation we have to compare the size of
4500 // the panel at control creation time with that of the frame client. If
4501 // they are the same we can use the standard Y position equation. If
4502 // not, then we must use the Frame Client's dimensions to position them
4503 // as that will be the eventual size of the panel after the frame resizes
4504 // it!
4505 //
4506 int wxWindowOS2::GetOS2ParentHeight(
4507 wxWindowOS2* pParent
4508 )
4509 {
4510 //
4511 // Case 1
4512 //
4513 if (pParent->IsKindOf(CLASSINFO(wxDialog)))
4514 return(pParent->GetClientSize().y);
4515
4516 //
4517 // Case 2 -- if we are one of the separately built standard Frame
4518 // children, like a statusbar, menubar, or toolbar we want to
4519 // use the frame, itself, for positioning. Otherwise we are
4520 // child window and want to use the Frame's client.
4521 //
4522 else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
4523 {
4524 if (IsKindOf(CLASSINFO(wxStatusBar)) ||
4525 IsKindOf(CLASSINFO(wxMenuBar)) ||
4526 IsKindOf(CLASSINFO(wxToolBar))
4527 )
4528 {
4529 if (IsKindOf(CLASSINFO(wxToolBar)))
4530 {
4531 wxFrame* pFrame = wxDynamicCast(GetParent(), wxFrame);
4532
4533 if (pFrame->GetToolBar() == this)
4534 return(pParent->GetSize().y);
4535 else
4536 return(pParent->GetClientSize().y);
4537 }
4538 else
4539 return(pParent->GetSize().y);
4540 }
4541 else
4542 return(pParent->GetClientSize().y);
4543 }
4544 //
4545 // Case -- this is for any window that is the sole child of a Frame.
4546 // The grandparent must exist and it must be of type CFrame
4547 // and it's height must be different. Otherwise the standard
4548 // applies.
4549 //
4550 else
4551 {
4552 return(pParent->GetClientSize().y);
4553 }
4554 return(0L);
4555 } // end of wxWindowOS2::GetOS2ParentHeight
4556
4557 //
4558 // OS/2 needs a lot extra manipulation to deal with layouts
4559 // for canvas windows, particularly scrolled ones.
4560 //
4561 wxWindowCreationHook::wxWindowCreationHook(
4562 wxWindow* pWinBeingCreated
4563 )
4564 {
4565 gpWinBeingCreated = pWinBeingCreated;
4566 } // end of wxWindowCreationHook::wxWindowCreationHook
4567
4568 wxWindowCreationHook::~wxWindowCreationHook()
4569 {
4570 gpWinBeingCreated = NULL;
4571 } // end of wxWindowCreationHook::~wxWindowCreationHook
4572
4573 // ===========================================================================
4574 // global functions
4575 // ===========================================================================
4576
4577 void wxGetCharSize(
4578 WXHWND hWnd
4579 , int* pX
4580 , int* pY
4581 ,wxFont* WXUNUSED(pTheFont)
4582 )
4583 {
4584 FONTMETRICS vFM;
4585 HPS hPS;
4586 BOOL rc;
4587
4588 hPS =::WinGetPS(hWnd);
4589
4590 rc = ::GpiQueryFontMetrics(hPS, sizeof(FONTMETRICS), &vFM);
4591 if (rc)
4592 {
4593 if (pX)
4594 *pX = vFM.lAveCharWidth;
4595 if (pY)
4596 *pY = vFM.lEmHeight + vFM.lExternalLeading;
4597 }
4598 else
4599 {
4600 if (pX)
4601 *pX = 10;
4602 if (pY)
4603 *pY = 15;
4604 }
4605 ::WinReleasePS(hPS);
4606 } // end of wxGetCharSize
4607
4608 //
4609 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
4610 // the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
4611 //
4612 int wxCharCodeOS2ToWX(
4613 int nKeySym
4614 )
4615 {
4616 int nId = 0;
4617
4618 switch (nKeySym)
4619 {
4620 case VK_BACKTAB: nId = WXK_BACK; break;
4621 case VK_TAB: nId = WXK_TAB; break;
4622 case VK_CLEAR: nId = WXK_CLEAR; break;
4623 case VK_ENTER: nId = WXK_RETURN; break;
4624 case VK_SHIFT: nId = WXK_SHIFT; break;
4625 case VK_CTRL: nId = WXK_CONTROL; break;
4626 case VK_PAUSE: nId = WXK_PAUSE; break;
4627 case VK_SPACE: nId = WXK_SPACE; break;
4628 case VK_ESC: nId = WXK_ESCAPE; break;
4629 case VK_END: nId = WXK_END; break;
4630 case VK_HOME : nId = WXK_HOME; break;
4631 case VK_LEFT : nId = WXK_LEFT; break;
4632 case VK_UP: nId = WXK_UP; break;
4633 case VK_RIGHT: nId = WXK_RIGHT; break;
4634 case VK_DOWN : nId = WXK_DOWN; break;
4635 case VK_PRINTSCRN: nId = WXK_PRINT; break;
4636 case VK_INSERT: nId = WXK_INSERT; break;
4637 case VK_DELETE: nId = WXK_DELETE; break;
4638 case VK_CAPSLOCK: nId = WXK_CAPITAL; break;
4639 case VK_F1: nId = WXK_F1; break;
4640 case VK_F2: nId = WXK_F2; break;
4641 case VK_F3: nId = WXK_F3; break;
4642 case VK_F4: nId = WXK_F4; break;
4643 case VK_F5: nId = WXK_F5; break;
4644 case VK_F6: nId = WXK_F6; break;
4645 case VK_F7: nId = WXK_F7; break;
4646 case VK_F8: nId = WXK_F8; break;
4647 case VK_F9: nId = WXK_F9; break;
4648 case VK_F10: nId = WXK_F10; break;
4649 case VK_F11: nId = WXK_F11; break;
4650 case VK_F12: nId = WXK_F12; break;
4651 case VK_F13: nId = WXK_F13; break;
4652 case VK_F14: nId = WXK_F14; break;
4653 case VK_F15: nId = WXK_F15; break;
4654 case VK_F16: nId = WXK_F16; break;
4655 case VK_F17: nId = WXK_F17; break;
4656 case VK_F18: nId = WXK_F18; break;
4657 case VK_F19: nId = WXK_F19; break;
4658 case VK_F20: nId = WXK_F20; break;
4659 case VK_F21: nId = WXK_F21; break;
4660 case VK_F22: nId = WXK_F22; break;
4661 case VK_F23: nId = WXK_F23; break;
4662 case VK_F24: nId = WXK_F24; break;
4663 case VK_OEM_1: nId = ';'; break;
4664 case VK_OEM_PLUS: nId = '+'; break;
4665 case VK_OEM_COMMA: nId = ','; break;
4666 case VK_OEM_MINUS: nId = '-'; break;
4667 case VK_OEM_PERIOD: nId = '.'; break;
4668 case VK_OEM_2: nId = '/'; break;
4669 case VK_OEM_3: nId = '~'; break;
4670 case VK_OEM_4: nId = '['; break;
4671 case VK_OEM_5: nId = '\\'; break;
4672 case VK_OEM_6: nId = ']'; break;
4673 case VK_OEM_7: nId = '\''; break;
4674 case VK_NUMLOCK: nId = WXK_NUMLOCK; break;
4675 case VK_SCRLLOCK: nId = WXK_SCROLL; break;
4676 default:
4677 {
4678 return 0;
4679 }
4680 }
4681 return nId;
4682 } // end of wxCharCodeOS2ToWX
4683
4684 int wxCharCodeWXToOS2(
4685 int nId
4686 , bool* bIsVirtual
4687 )
4688 {
4689 int nKeySym = 0;
4690
4691 *bIsVirtual = TRUE;
4692 switch (nId)
4693 {
4694 case WXK_CLEAR: nKeySym = VK_CLEAR; break;
4695 case WXK_SHIFT: nKeySym = VK_SHIFT; break;
4696 case WXK_CONTROL: nKeySym = VK_CTRL; break;
4697 case WXK_PAUSE: nKeySym = VK_PAUSE; break;
4698 case WXK_END: nKeySym = VK_END; break;
4699 case WXK_HOME : nKeySym = VK_HOME; break;
4700 case WXK_LEFT : nKeySym = VK_LEFT; break;
4701 case WXK_UP: nKeySym = VK_UP; break;
4702 case WXK_RIGHT: nKeySym = VK_RIGHT; break;
4703 case WXK_DOWN : nKeySym = VK_DOWN; break;
4704 case WXK_PRINT: nKeySym = VK_PRINTSCRN; break;
4705 case WXK_INSERT: nKeySym = VK_INSERT; break;
4706 case WXK_DELETE: nKeySym = VK_DELETE; break;
4707 case WXK_F1: nKeySym = VK_F1; break;
4708 case WXK_F2: nKeySym = VK_F2; break;
4709 case WXK_F3: nKeySym = VK_F3; break;
4710 case WXK_F4: nKeySym = VK_F4; break;
4711 case WXK_F5: nKeySym = VK_F5; break;
4712 case WXK_F6: nKeySym = VK_F6; break;
4713 case WXK_F7: nKeySym = VK_F7; break;
4714 case WXK_F8: nKeySym = VK_F8; break;
4715 case WXK_F9: nKeySym = VK_F9; break;
4716 case WXK_F10: nKeySym = VK_F10; break;
4717 case WXK_F11: nKeySym = VK_F11; break;
4718 case WXK_F12: nKeySym = VK_F12; break;
4719 case WXK_F13: nKeySym = VK_F13; break;
4720 case WXK_F14: nKeySym = VK_F14; break;
4721 case WXK_F15: nKeySym = VK_F15; break;
4722 case WXK_F16: nKeySym = VK_F16; break;
4723 case WXK_F17: nKeySym = VK_F17; break;
4724 case WXK_F18: nKeySym = VK_F18; break;
4725 case WXK_F19: nKeySym = VK_F19; break;
4726 case WXK_F20: nKeySym = VK_F20; break;
4727 case WXK_F21: nKeySym = VK_F21; break;
4728 case WXK_F22: nKeySym = VK_F22; break;
4729 case WXK_F23: nKeySym = VK_F23; break;
4730 case WXK_F24: nKeySym = VK_F24; break;
4731 case WXK_NUMLOCK: nKeySym = VK_NUMLOCK; break;
4732 case WXK_SCROLL: nKeySym = VK_SCRLLOCK; break;
4733 default:
4734 {
4735 *bIsVirtual = FALSE;
4736 nKeySym = nId;
4737 break;
4738 }
4739 }
4740 return nKeySym;
4741 } // end of wxCharCodeWXToOS2
4742
4743 wxWindow* wxGetActiveWindow()
4744 {
4745 HWND hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
4746
4747 if (hWnd != 0)
4748 {
4749 return wxFindWinFromHandle((WXHWND)hWnd);
4750 }
4751 return NULL;
4752 } // end of wxGetActiveWindow
4753
4754 #ifdef __WXDEBUG__
4755 const char* wxGetMessageName(
4756 int nMessage)
4757 {
4758 switch (nMessage)
4759 {
4760 case 0x0000: return "WM_NULL";
4761 case 0x0001: return "WM_CREATE";
4762 case 0x0002: return "WM_DESTROY";
4763 case 0x0004: return "WM_ENABLE";
4764 case 0x0005: return "WM_SHOW";
4765 case 0x0006: return "WM_MOVE";
4766 case 0x0007: return "WM_SIZE";
4767 case 0x0008: return "WM_ADJUSTWINDOWPOS";
4768 case 0x0009: return "WM_CALCVALIDRECTS";
4769 case 0x000A: return "WM_SETWINDOWPARAMS";
4770 case 0x000B: return "WM_QUERYWINDOWPARAMS";
4771 case 0x000C: return "WM_HITTEST";
4772 case 0x000D: return "WM_ACTIVATE";
4773 case 0x000F: return "WM_SETFOCUS";
4774 case 0x0010: return "WM_SETSELECTION";
4775 case 0x0011: return "WM_PPAINT";
4776 case 0x0012: return "WM_PSETFOCUS";
4777 case 0x0013: return "WM_PSYSCOLORCHANGE";
4778 case 0x0014: return "WM_PSIZE";
4779 case 0x0015: return "WM_PACTIVATE";
4780 case 0x0016: return "WM_PCONTROL";
4781 case 0x0020: return "WM_COMMAND";
4782 case 0x0021: return "WM_SYSCOMMAND";
4783 case 0x0022: return "WM_HELP";
4784 case 0x0023: return "WM_PAINT";
4785 case 0x0024: return "WM_TIMER";
4786 case 0x0025: return "WM_SEM1";
4787 case 0x0026: return "WM_SEM2";
4788 case 0x0027: return "WM_SEM3";
4789 case 0x0028: return "WM_SEM4";
4790 case 0x0029: return "WM_CLOSE";
4791 case 0x002A: return "WM_QUIT";
4792 case 0x002B: return "WM_SYSCOLORCHANGE";
4793 case 0x002D: return "WM_SYSVALUECHANGE";
4794 case 0x002E: return "WM_APPTERMINATENOTIFY";
4795 case 0x002F: return "WM_PRESPARAMCHANGED";
4796 // Control notification messages
4797 case 0x0030: return "WM_CONTROL";
4798 case 0x0031: return "WM_VSCROLL";
4799 case 0x0032: return "WM_HSCROLL";
4800 case 0x0033: return "WM_INITMENU";
4801 case 0x0034: return "WM_MENUSELECT";
4802 case 0x0035: return "WM_MENUSEND";
4803 case 0x0036: return "WM_DRAWITEM";
4804 case 0x0037: return "WM_MEASUREITEM";
4805 case 0x0038: return "WM_CONTROLPOINTER";
4806 case 0x003A: return "WM_QUERYDLGCODE";
4807 case 0x003B: return "WM_INITDLG";
4808 case 0x003C: return "WM_SUBSTITUTESTRING";
4809 case 0x003D: return "WM_MATCHMNEMONIC";
4810 case 0x003E: return "WM_SAVEAPPLICATION";
4811 case 0x0129: return "WM_CTLCOLORCHANGE";
4812 case 0x0130: return "WM_QUERYCTLTYPE";
4813 // Frame messages
4814 case 0x0040: return "WM_FLASHWINDOW";
4815 case 0x0041: return "WM_FORMATFRAME";
4816 case 0x0042: return "WM_UPDATEFRAME";
4817 case 0x0043: return "WM_FOCUSCHANGE";
4818 case 0x0044: return "WM_SETBORDERSIZE";
4819 case 0x0045: return "WM_TRACKFRAME";
4820 case 0x0046: return "WM_MINMAXFRAME";
4821 case 0x0047: return "WM_SETICON";
4822 case 0x0048: return "WM_QUERYICON";
4823 case 0x0049: return "WM_SETACCELTABLE";
4824 case 0x004A: return "WM_QUERYACCELTABLE";
4825 case 0x004B: return "WM_TRANSLATEACCEL";
4826 case 0x004C: return "WM_QUERYTRACKINFO";
4827 case 0x004D: return "WM_QUERYBORDERSIZE";
4828 case 0x004E: return "WM_NEXTMENU";
4829 case 0x004F: return "WM_ERASEBACKGROUND";
4830 case 0x0050: return "WM_QUERYFRAMEINFO";
4831 case 0x0051: return "WM_QUERYFOCUSCHAIN";
4832 case 0x0052: return "WM_OWNERPOSCHANGE";
4833 case 0x0053: return "WM_CACLFRAMERECT";
4834 case 0x0055: return "WM_WINDOWPOSCHANGED";
4835 case 0x0056: return "WM_ADJUSTFRAMEPOS";
4836 case 0x0059: return "WM_QUERYFRAMECTLCOUNT";
4837 case 0x005B: return "WM_QUERYHELPINFO";
4838 case 0x005C: return "WM_SETHELPINFO";
4839 case 0x005D: return "WM_ERROR";
4840 case 0x005E: return "WM_REALIZEPALETTE";
4841 // Clipboard messages
4842 case 0x0060: return "WM_RENDERFMT";
4843 case 0x0061: return "WM_RENDERALLFMTS";
4844 case 0x0062: return "WM_DESTROYCLIPBOARD";
4845 case 0x0063: return "WM_PAINTCLIPBOARD";
4846 case 0x0064: return "WM_SIZECLIPBOARD";
4847 case 0x0065: return "WM_HSCROLLCLIPBOARD";
4848 case 0x0066: return "WM_VSCROLLCLIPBOARD";
4849 case 0x0067: return "WM_DRAWCLIPBOARD";
4850 // mouse messages
4851 case 0x0070: return "WM_MOUSEMOVE";
4852 case 0x0071: return "WM_BUTTON1DOWN";
4853 case 0x0072: return "WM_BUTTON1UP";
4854 case 0x0073: return "WM_BUTTON1DBLCLK";
4855 case 0x0074: return "WM_BUTTON2DOWN";
4856 case 0x0075: return "WM_BUTTON2UP";
4857 case 0x0076: return "WM_BUTTON2DBLCLK";
4858 case 0x0077: return "WM_BUTTON3DOWN";
4859 case 0x0078: return "WM_BUTTON3UP";
4860 case 0x0079: return "WM_BUTTON3DBLCLK";
4861 case 0x007D: return "WM_MOUSEMAP";
4862 case 0x007E: return "WM_VRNDISABLED";
4863 case 0x007F: return "WM_VRNENABLED";
4864 case 0x0410: return "WM_CHORD";
4865 case 0x0411: return "WM_BUTTON1MOTIONSTART";
4866 case 0x0412: return "WM_BUTTON1MOTIONEND";
4867 case 0x0413: return "WM_BUTTON1CLICK";
4868 case 0x0414: return "WM_BUTTON2MOTIONSTART";
4869 case 0x0415: return "WM_BUTTON2MOTIONEND";
4870 case 0x0416: return "WM_BUTTON2CLICK";
4871 case 0x0417: return "WM_BUTTON3MOTIONSTART";
4872 case 0x0418: return "WM_BUTTON3MOTIONEND";
4873 case 0x0419: return "WM_BUTTON3CLICK";
4874 case 0x0420: return "WM_BEGINDRAG";
4875 case 0x0421: return "WM_ENDDRAG";
4876 case 0x0422: return "WM_SINGLESELECT";
4877 case 0x0423: return "WM_OPEN";
4878 case 0x0424: return "WM_CONTEXTMENU";
4879 case 0x0425: return "WM_CONTEXTHELP";
4880 case 0x0426: return "WM_TEXTEDIT";
4881 case 0x0427: return "WM_BEGINSELECT";
4882 case 0x0228: return "WM_ENDSELECT";
4883 case 0x0429: return "WM_PICKUP";
4884 case 0x04C0: return "WM_PENFIRST";
4885 case 0x04FF: return "WM_PENLAST";
4886 case 0x0500: return "WM_MMPMFIRST";
4887 case 0x05FF: return "WM_MMPMLAST";
4888 case 0x0600: return "WM_STDDLGFIRST";
4889 case 0x06FF: return "WM_STDDLGLAST";
4890 case 0x0BD0: return "WM_BIDI_FIRST";
4891 case 0x0BFF: return "WM_BIDI_LAST";
4892 // keyboard input
4893 case 0x007A: return "WM_CHAR";
4894 case 0x007B: return "WM_VIOCHAR";
4895 // DDE messages
4896 case 0x00A0: return "WM_DDE_INITIATE";
4897 case 0x00A1: return "WM_DDE_REQUEST";
4898 case 0x00A2: return "WM_DDE_ACK";
4899 case 0x00A3: return "WM_DDE_DATA";
4900 case 0x00A4: return "WM_DDE_ADVISE";
4901 case 0x00A5: return "WM_DDE_UNADVISE";
4902 case 0x00A6: return "WM_DDE_POKE";
4903 case 0x00A7: return "WM_DDE_EXECUTE";
4904 case 0x00A8: return "WM_DDE_TERMINATE";
4905 case 0x00A9: return "WM_DDE_INITIATEACK";
4906 case 0x00AF: return "WM_DDE_LAST";
4907 // Buttons
4908 case 0x0120: return "BM_CLICK";
4909 case 0x0121: return "BM_QUERYCHECKINDEX";
4910 case 0x0122: return "BM_QUERYHILITE";
4911 case 0x0123: return "BM_SETHILITE";
4912 case 0x0124: return "BM_QUERYCHECK";
4913 case 0x0125: return "BM_SETCHECK";
4914 case 0x0126: return "BM_SETDEFAULT";
4915 case 0x0128: return "BM_AUTOSIZE";
4916 // Combo boxes
4917 case 0x029A: return "CBID_LIST";
4918 case 0x029B: return "CBID_EDIT";
4919 case 0x0170: return "CBM_SHOWLIST";
4920 case 0x0171: return "CBM_HILITE";
4921 case 0x0172: return "CBM_ISLISTSHOWING";
4922 // Edit fields
4923 case 0x0140: return "EM_QUERYCHANGED";
4924 case 0x0141: return "EM_QUERYSEL";
4925 case 0x0142: return "EM_SETSEL";
4926 case 0x0143: return "EM_SETTEXTLIMIT";
4927 case 0x0144: return "EM_CUT";
4928 case 0x0145: return "EM_COPY";
4929 case 0x0146: return "EM_CLEAR";
4930 case 0x0147: return "EM_PASTE";
4931 case 0x0148: return "EM_QUERYFIRSTCHAR";
4932 case 0x0149: return "EM_SETFIRSTCHAR";
4933 case 0x014A: return "EM_QUERYREADONLY";
4934 case 0x014B: return "EM_SETREADONLY";
4935 case 0x014C: return "EM_SETINSERTMODE";
4936 // Listboxes
4937 case 0x0160: return "LM_QUERYITEMCOUNT";
4938 case 0x0161: return "LM_INSERTITEM";
4939 case 0x0162: return "LM_SETOPENINDEX";
4940 case 0x0163: return "LM_DELETEITEM";
4941 case 0x0164: return "LM_SELECTITEM";
4942 case 0x0165: return "LM_QUERYSELECTION";
4943 case 0x0166: return "LM_SETITEMTEXT";
4944 case 0x0167: return "LM_QUERYITEMTEXTLENGTH";
4945 case 0x0168: return "LM_QUERYITEMTEXT";
4946 case 0x0169: return "LM_SETITEMHANDLE";
4947 case 0x016A: return "LM_QUERYITEMHANDLE";
4948 case 0x016B: return "LM_SEARCHSTRING";
4949 case 0x016C: return "LM_SETITEMHEIGHT";
4950 case 0x016D: return "LM_QUERYTOPINDEX";
4951 case 0x016E: return "LM_DELETEALL";
4952 case 0x016F: return "LM_INSERTMULITEMS";
4953 case 0x0660: return "LM_SETITEMWIDTH";
4954 // Menus
4955 case 0x0180: return "MM_INSERTITEM";
4956 case 0x0181: return "MM_DELETEITEM";
4957 case 0x0182: return "MM_QUERYITEM";
4958 case 0x0183: return "MM_SETITEM";
4959 case 0x0184: return "MM_QUERYITEMCOUNT";
4960 case 0x0185: return "MM_STARTMENUMODE";
4961 case 0x0186: return "MM_ENDMENUMODE";
4962 case 0x0188: return "MM_REMOVEITEM";
4963 case 0x0189: return "MM_SELECTITEM";
4964 case 0x018A: return "MM_QUERYSELITEMID";
4965 case 0x018B: return "MM_QUERYITEMTEXT";
4966 case 0x018C: return "MM_QUERYITEMTEXTLENGTH";
4967 case 0x018D: return "MM_SETITEMHANDLE";
4968 case 0x018E: return "MM_SETITEMTEXT";
4969 case 0x018F: return "MM_ITEMPOSITIONFROMID";
4970 case 0x0190: return "MM_ITEMIDFROMPOSITION";
4971 case 0x0191: return "MM_QUERYITEMATTR";
4972 case 0x0192: return "MM_SETITEMATTR";
4973 case 0x0193: return "MM_ISITEMVALID";
4974 case 0x0194: return "MM_QUERYITEMRECT";
4975 case 0x0431: return "MM_QUERYDEFAULTITEMID";
4976 case 0x0432: return "MM_SETDEFAULTITEMID";
4977 // Scrollbars
4978 case 0x01A0: return "SBM_SETSCROLLBAR";
4979 case 0x01A1: return "SBM_SETPOS";
4980 case 0x01A2: return "SBM_QUERYPOS";
4981 case 0x01A3: return "SBM_QUERYRANGE";
4982 case 0x01A6: return "SBM_SETTHUMBSIZE";
4983
4984 // Help messages
4985 case 0x0F00: return "WM_HELPBASE";
4986 case 0x0FFF: return "WM_HELPTOP";
4987 // Beginning of user defined messages
4988 case 0x1000: return "WM_USER";
4989
4990 // wxWidgets user defined types
4991
4992 // listview
4993 // case 0x1000 + 0: return "LVM_GETBKCOLOR";
4994 case 0x1000 + 1: return "LVM_SETBKCOLOR";
4995 case 0x1000 + 2: return "LVM_GETIMAGELIST";
4996 case 0x1000 + 3: return "LVM_SETIMAGELIST";
4997 case 0x1000 + 4: return "LVM_GETITEMCOUNT";
4998 case 0x1000 + 5: return "LVM_GETITEMA";
4999 case 0x1000 + 75: return "LVM_GETITEMW";
5000 case 0x1000 + 6: return "LVM_SETITEMA";
5001 case 0x1000 + 76: return "LVM_SETITEMW";
5002 case 0x1000 + 7: return "LVM_INSERTITEMA";
5003 case 0x1000 + 77: return "LVM_INSERTITEMW";
5004 case 0x1000 + 8: return "LVM_DELETEITEM";
5005 case 0x1000 + 9: return "LVM_DELETEALLITEMS";
5006 case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
5007 case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
5008 case 0x1000 + 12: return "LVM_GETNEXTITEM";
5009 case 0x1000 + 13: return "LVM_FINDITEMA";
5010 case 0x1000 + 83: return "LVM_FINDITEMW";
5011 case 0x1000 + 14: return "LVM_GETITEMRECT";
5012 case 0x1000 + 15: return "LVM_SETITEMPOSITION";
5013 case 0x1000 + 16: return "LVM_GETITEMPOSITION";
5014 case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
5015 case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
5016 case 0x1000 + 18: return "LVM_HITTEST";
5017 case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
5018 case 0x1000 + 20: return "LVM_SCROLL";
5019 case 0x1000 + 21: return "LVM_REDRAWITEMS";
5020 case 0x1000 + 22: return "LVM_ARRANGE";
5021 case 0x1000 + 23: return "LVM_EDITLABELA";
5022 case 0x1000 + 118: return "LVM_EDITLABELW";
5023 case 0x1000 + 24: return "LVM_GETEDITCONTROL";
5024 case 0x1000 + 25: return "LVM_GETCOLUMNA";
5025 case 0x1000 + 95: return "LVM_GETCOLUMNW";
5026 case 0x1000 + 26: return "LVM_SETCOLUMNA";
5027 case 0x1000 + 96: return "LVM_SETCOLUMNW";
5028 case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
5029 case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
5030 case 0x1000 + 28: return "LVM_DELETECOLUMN";
5031 case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
5032 case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
5033 case 0x1000 + 31: return "LVM_GETHEADER";
5034 case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
5035 case 0x1000 + 34: return "LVM_GETVIEWRECT";
5036 case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
5037 case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
5038 case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
5039 case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
5040 case 0x1000 + 39: return "LVM_GETTOPINDEX";
5041 case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
5042 case 0x1000 + 41: return "LVM_GETORIGIN";
5043 case 0x1000 + 42: return "LVM_UPDATE";
5044 case 0x1000 + 43: return "LVM_SETITEMSTATE";
5045 case 0x1000 + 44: return "LVM_GETITEMSTATE";
5046 case 0x1000 + 45: return "LVM_GETITEMTEXTA";
5047 case 0x1000 + 115: return "LVM_GETITEMTEXTW";
5048 case 0x1000 + 46: return "LVM_SETITEMTEXTA";
5049 case 0x1000 + 116: return "LVM_SETITEMTEXTW";
5050 case 0x1000 + 47: return "LVM_SETITEMCOUNT";
5051 case 0x1000 + 48: return "LVM_SORTITEMS";
5052 case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
5053 case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
5054 case 0x1000 + 51: return "LVM_GETITEMSPACING";
5055 case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
5056 case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
5057 case 0x1000 + 53: return "LVM_SETICONSPACING";
5058 case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
5059 case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
5060 case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
5061 case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
5062 case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
5063 case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
5064 case 0x1000 + 60: return "LVM_SETHOTITEM";
5065 case 0x1000 + 61: return "LVM_GETHOTITEM";
5066 case 0x1000 + 62: return "LVM_SETHOTCURSOR";
5067 case 0x1000 + 63: return "LVM_GETHOTCURSOR";
5068 case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
5069 case 0x1000 + 65: return "LVM_SETWORKAREA";
5070
5071 // tree view
5072 case 0x1100 + 0: return "TVM_INSERTITEMA";
5073 case 0x1100 + 50: return "TVM_INSERTITEMW";
5074 case 0x1100 + 1: return "TVM_DELETEITEM";
5075 case 0x1100 + 2: return "TVM_EXPAND";
5076 case 0x1100 + 4: return "TVM_GETITEMRECT";
5077 case 0x1100 + 5: return "TVM_GETCOUNT";
5078 case 0x1100 + 6: return "TVM_GETINDENT";
5079 case 0x1100 + 7: return "TVM_SETINDENT";
5080 case 0x1100 + 8: return "TVM_GETIMAGELIST";
5081 case 0x1100 + 9: return "TVM_SETIMAGELIST";
5082 case 0x1100 + 10: return "TVM_GETNEXTITEM";
5083 case 0x1100 + 11: return "TVM_SELECTITEM";
5084 case 0x1100 + 12: return "TVM_GETITEMA";
5085 case 0x1100 + 62: return "TVM_GETITEMW";
5086 case 0x1100 + 13: return "TVM_SETITEMA";
5087 case 0x1100 + 63: return "TVM_SETITEMW";
5088 case 0x1100 + 14: return "TVM_EDITLABELA";
5089 case 0x1100 + 65: return "TVM_EDITLABELW";
5090 case 0x1100 + 15: return "TVM_GETEDITCONTROL";
5091 case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
5092 case 0x1100 + 17: return "TVM_HITTEST";
5093 case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
5094 case 0x1100 + 19: return "TVM_SORTCHILDREN";
5095 case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
5096 case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
5097 case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
5098 case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
5099 case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
5100 case 0x1100 + 24: return "TVM_SETTOOLTIPS";
5101 case 0x1100 + 25: return "TVM_GETTOOLTIPS";
5102
5103 // header
5104 case 0x1200 + 0: return "HDM_GETITEMCOUNT";
5105 case 0x1200 + 1: return "HDM_INSERTITEMA";
5106 case 0x1200 + 10: return "HDM_INSERTITEMW";
5107 case 0x1200 + 2: return "HDM_DELETEITEM";
5108 case 0x1200 + 3: return "HDM_GETITEMA";
5109 case 0x1200 + 11: return "HDM_GETITEMW";
5110 case 0x1200 + 4: return "HDM_SETITEMA";
5111 case 0x1200 + 12: return "HDM_SETITEMW";
5112 case 0x1200 + 5: return "HDM_LAYOUT";
5113 case 0x1200 + 6: return "HDM_HITTEST";
5114 case 0x1200 + 7: return "HDM_GETITEMRECT";
5115 case 0x1200 + 8: return "HDM_SETIMAGELIST";
5116 case 0x1200 + 9: return "HDM_GETIMAGELIST";
5117 case 0x1200 + 15: return "HDM_ORDERTOINDEX";
5118 case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
5119 case 0x1200 + 17: return "HDM_GETORDERARRAY";
5120 case 0x1200 + 18: return "HDM_SETORDERARRAY";
5121 case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
5122
5123 // tab control
5124 case 0x1300 + 2: return "TCM_GETIMAGELIST";
5125 case 0x1300 + 3: return "TCM_SETIMAGELIST";
5126 case 0x1300 + 4: return "TCM_GETITEMCOUNT";
5127 case 0x1300 + 5: return "TCM_GETITEMA";
5128 case 0x1300 + 60: return "TCM_GETITEMW";
5129 case 0x1300 + 6: return "TCM_SETITEMA";
5130 case 0x1300 + 61: return "TCM_SETITEMW";
5131 case 0x1300 + 7: return "TCM_INSERTITEMA";
5132 case 0x1300 + 62: return "TCM_INSERTITEMW";
5133 case 0x1300 + 8: return "TCM_DELETEITEM";
5134 case 0x1300 + 9: return "TCM_DELETEALLITEMS";
5135 case 0x1300 + 10: return "TCM_GETITEMRECT";
5136 case 0x1300 + 11: return "TCM_GETCURSEL";
5137 case 0x1300 + 12: return "TCM_SETCURSEL";
5138 case 0x1300 + 13: return "TCM_HITTEST";
5139 case 0x1300 + 14: return "TCM_SETITEMEXTRA";
5140 case 0x1300 + 40: return "TCM_ADJUSTRECT";
5141 case 0x1300 + 41: return "TCM_SETITEMSIZE";
5142 case 0x1300 + 42: return "TCM_REMOVEIMAGE";
5143 case 0x1300 + 43: return "TCM_SETPADDING";
5144 case 0x1300 + 44: return "TCM_GETROWCOUNT";
5145 case 0x1300 + 45: return "TCM_GETTOOLTIPS";
5146 case 0x1300 + 46: return "TCM_SETTOOLTIPS";
5147 case 0x1300 + 47: return "TCM_GETCURFOCUS";
5148 case 0x1300 + 48: return "TCM_SETCURFOCUS";
5149 case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
5150 case 0x1300 + 50: return "TCM_DESELECTALL";
5151
5152 // toolbar
5153 case WM_USER+1000+1: return "TB_ENABLEBUTTON";
5154 case WM_USER+1000+2: return "TB_CHECKBUTTON";
5155 case WM_USER+1000+3: return "TB_PRESSBUTTON";
5156 case WM_USER+1000+4: return "TB_HIDEBUTTON";
5157 case WM_USER+1000+5: return "TB_INDETERMINATE";
5158 case WM_USER+1000+9: return "TB_ISBUTTONENABLED";
5159 case WM_USER+1000+10: return "TB_ISBUTTONCHECKED";
5160 case WM_USER+1000+11: return "TB_ISBUTTONPRESSED";
5161 case WM_USER+1000+12: return "TB_ISBUTTONHIDDEN";
5162 case WM_USER+1000+13: return "TB_ISBUTTONINDETERMINATE";
5163 case WM_USER+1000+17: return "TB_SETSTATE";
5164 case WM_USER+1000+18: return "TB_GETSTATE";
5165 case WM_USER+1000+19: return "TB_ADDBITMAP";
5166 case WM_USER+1000+20: return "TB_ADDBUTTONS";
5167 case WM_USER+1000+21: return "TB_INSERTBUTTON";
5168 case WM_USER+1000+22: return "TB_DELETEBUTTON";
5169 case WM_USER+1000+23: return "TB_GETBUTTON";
5170 case WM_USER+1000+24: return "TB_BUTTONCOUNT";
5171 case WM_USER+1000+25: return "TB_COMMANDTOINDEX";
5172 case WM_USER+1000+26: return "TB_SAVERESTOREA";
5173 case WM_USER+1000+76: return "TB_SAVERESTOREW";
5174 case WM_USER+1000+27: return "TB_CUSTOMIZE";
5175 case WM_USER+1000+28: return "TB_ADDSTRINGA";
5176 case WM_USER+1000+77: return "TB_ADDSTRINGW";
5177 case WM_USER+1000+29: return "TB_GETITEMRECT";
5178 case WM_USER+1000+30: return "TB_BUTTONSTRUCTSIZE";
5179 case WM_USER+1000+31: return "TB_SETBUTTONSIZE";
5180 case WM_USER+1000+32: return "TB_SETBITMAPSIZE";
5181 case WM_USER+1000+33: return "TB_AUTOSIZE";
5182 case WM_USER+1000+35: return "TB_GETTOOLTIPS";
5183 case WM_USER+1000+36: return "TB_SETTOOLTIPS";
5184 case WM_USER+1000+37: return "TB_SETPARENT";
5185 case WM_USER+1000+39: return "TB_SETROWS";
5186 case WM_USER+1000+40: return "TB_GETROWS";
5187 case WM_USER+1000+42: return "TB_SETCMDID";
5188 case WM_USER+1000+43: return "TB_CHANGEBITMAP";
5189 case WM_USER+1000+44: return "TB_GETBITMAP";
5190 case WM_USER+1000+45: return "TB_GETBUTTONTEXTA";
5191 case WM_USER+1000+75: return "TB_GETBUTTONTEXTW";
5192 case WM_USER+1000+46: return "TB_REPLACEBITMAP";
5193 case WM_USER+1000+47: return "TB_SETINDENT";
5194 case WM_USER+1000+48: return "TB_SETIMAGELIST";
5195 case WM_USER+1000+49: return "TB_GETIMAGELIST";
5196 case WM_USER+1000+50: return "TB_LOADIMAGES";
5197 case WM_USER+1000+51: return "TB_GETRECT";
5198 case WM_USER+1000+52: return "TB_SETHOTIMAGELIST";
5199 case WM_USER+1000+53: return "TB_GETHOTIMAGELIST";
5200 case WM_USER+1000+54: return "TB_SETDISABLEDIMAGELIST";
5201 case WM_USER+1000+55: return "TB_GETDISABLEDIMAGELIST";
5202 case WM_USER+1000+56: return "TB_SETSTYLE";
5203 case WM_USER+1000+57: return "TB_GETSTYLE";
5204 case WM_USER+1000+58: return "TB_GETBUTTONSIZE";
5205 case WM_USER+1000+59: return "TB_SETBUTTONWIDTH";
5206 case WM_USER+1000+60: return "TB_SETMAXTEXTROWS";
5207 case WM_USER+1000+61: return "TB_GETTEXTROWS";
5208 case WM_USER+1000+41: return "TB_GETBITMAPFLAGS";
5209
5210 default:
5211 static char s_szBuf[128];
5212 sprintf(s_szBuf, "<unknown message = %d>", nMessage);
5213 return s_szBuf;
5214 }
5215 return NULL;
5216 } // end of wxGetMessageName
5217
5218 #endif // __WXDEBUG__
5219
5220 // Unused?
5221 #if 0
5222 static void TranslateKbdEventToMouse(
5223 wxWindow* pWin
5224 , int* pX
5225 , int* pY
5226 , ULONG* pFlags
5227 )
5228 {
5229 //
5230 // Construct the key mask
5231 ULONG& fwKeys = *pFlags;
5232
5233 fwKeys = VK_BUTTON2;
5234 if ((::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x100) != 0)
5235 fwKeys |= VK_CTRL;
5236 if ((::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x100) != 0)
5237 fwKeys |= VK_SHIFT;
5238
5239 //
5240 // Simulate right mouse button click
5241 //
5242 POINTL vPoint;
5243
5244 ::WinQueryMsgPos(vHabmain, &vPoint);
5245 *pX = vPoint.x;
5246 *pY = vPoint.y;
5247
5248 pWin->ScreenToClient(pX, pY);
5249 } // end of TranslateKbdEventToMouse
5250 #endif
5251
5252 // Find the wxWindow at the current mouse position, returning the mouse
5253 // position.
5254 wxWindow* wxFindWindowAtPointer(
5255 wxPoint& WXUNUSED(rPt)
5256 )
5257 {
5258 return wxFindWindowAtPoint(wxGetMousePosition());
5259 }
5260
5261 wxWindow* wxFindWindowAtPoint(
5262 const wxPoint& rPt
5263 )
5264 {
5265 POINTL vPt2;
5266
5267 vPt2.x = rPt.x;
5268 vPt2.y = rPt.y;
5269
5270 HWND hWndHit = ::WinWindowFromPoint(HWND_DESKTOP, &vPt2, FALSE);
5271 wxWindow* pWin = wxFindWinFromHandle((WXHWND)hWndHit) ;
5272 HWND hWnd = hWndHit;
5273
5274 //
5275 // Try to find a window with a wxWindow associated with it
5276 //
5277 while (!pWin && (hWnd != 0))
5278 {
5279 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
5280 pWin = wxFindWinFromHandle((WXHWND)hWnd) ;
5281 }
5282 return pWin;
5283 }
5284
5285 // Get the current mouse position.
5286 wxPoint wxGetMousePosition()
5287 {
5288 POINTL vPt;
5289
5290 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
5291 return wxPoint(vPt.x, vPt.y);
5292 }
5293
5294 wxWindowOS2* FindWindowForMouseEvent(
5295 wxWindow* pWin
5296 , short* pnX
5297 , short* pnY
5298 )
5299 {
5300 HWND hWnd = GetHwndOf(pWin);
5301 HWND hWndUnderMouse;
5302 POINTL vPoint;
5303 BOOL rcEnabled = FALSE;
5304 BOOL rcVisible = FALSE;
5305
5306 ::WinQueryPointerPos(HWND_DESKTOP, &vPoint);
5307 hWndUnderMouse = ::WinWindowFromPoint(HWND_DESKTOP, &vPoint, TRUE);
5308 if (hWndUnderMouse != HWND_DESKTOP)
5309 {
5310 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5311
5312 if (pWinUnderMouse)
5313 {
5314 wxWindowList::compatibility_iterator current = pWinUnderMouse->GetChildren().GetFirst();
5315 wxWindow* pGrandChild = NULL;
5316 RECTL vRect;
5317 POINTL vPoint2;
5318
5319 ::WinMapWindowPoints(HWND_DESKTOP, hWndUnderMouse, &vPoint, 1);
5320 //
5321 // Find a child window mouse might be under
5322 //
5323 while (current)
5324 {
5325 wxWindow* pChild = current->GetData();
5326
5327 vPoint2.x = vPoint.x;
5328 vPoint2.y = vPoint.y;
5329 ::WinMapWindowPoints(hWndUnderMouse, pChild->GetHWND(), &vPoint2, 1);
5330 ::WinQueryWindowRect(pChild->GetHWND(), &vRect);
5331 if (::WinPtInRect(vHabmain, &vRect, &vPoint2))
5332 {
5333 if (pChild->IsTopLevel())
5334 {
5335 POINTL vPoint3;
5336 wxWindowList::compatibility_iterator current2 =pChild->GetChildren().GetFirst();
5337
5338 while (current2)
5339 {
5340 wxWindow* pGrandChild = current2->GetData();
5341
5342 vPoint3.x = vPoint2.x;
5343 vPoint3.y = vPoint2.y;
5344 ::WinMapWindowPoints( pChild->GetHWND()
5345 ,pGrandChild->GetHWND()
5346 ,&vPoint3
5347 ,1
5348 );
5349 ::WinQueryWindowRect(pGrandChild->GetHWND(), &vRect);
5350 if (::WinPtInRect(vHabmain, &vRect, &vPoint3))
5351 {
5352 hWndUnderMouse = GetHwndOf(pGrandChild);
5353 pWinUnderMouse = pGrandChild;
5354 break;
5355 }
5356 current2 = current2->GetNext();
5357 }
5358 if (pGrandChild)
5359 break;
5360 }
5361 hWndUnderMouse = GetHwndOf(pChild);
5362 pWinUnderMouse = pChild;
5363 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5364 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5365 if (rcVisible && rcEnabled)
5366 break;
5367 }
5368 current = current->GetNext();
5369 }
5370 }
5371 }
5372 rcVisible = ::WinIsWindowVisible(hWndUnderMouse);
5373 rcEnabled = ::WinIsWindowEnabled(hWndUnderMouse);
5374
5375
5376 //
5377 // Check that we have a child window which is susceptible to receive mouse
5378 // events: for this it must be shown and enabled
5379 //
5380 if ( hWndUnderMouse &&
5381 hWndUnderMouse != hWnd &&
5382 rcVisible && rcEnabled)
5383 {
5384 wxWindow* pWinUnderMouse = wxFindWinFromHandle((WXHWND)hWndUnderMouse);
5385
5386 if (pWinUnderMouse)
5387 {
5388 //
5389 // Translate the mouse coords to the other window coords
5390 //
5391 pWin = pWinUnderMouse;
5392 }
5393 }
5394 return pWin;
5395 } // end of FindWindowForMouseEvent
5396