]> git.saurik.com Git - wxWidgets.git/blob - src/os2/accel.cpp
guard against nullptr
[wxWidgets.git] / src / os2 / accel.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/accel.cpp
3 // Purpose: wxAcceleratorTable
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #include "wx/accel.h"
16
17 #ifndef WX_PRECOMP
18 #include <stdio.h>
19 #include "wx/window.h"
20 #include "wx/app.h"
21 #include "wx/frame.h"
22 #endif
23
24 #include "wx/os2/private.h"
25
26
27 IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject)
28
29 class WXDLLEXPORT wxAcceleratorRefData: public wxObjectRefData
30 {
31 friend class WXDLLEXPORT wxAcceleratorTable;
32 public:
33 wxAcceleratorRefData();
34 virtual ~wxAcceleratorRefData();
35
36 inline HACCEL GetHACCEL() const { return m_hAccel; }
37 protected:
38 HACCEL m_hAccel;
39 bool m_ok;
40 };
41
42 #define M_ACCELDATA ((wxAcceleratorRefData *)m_refData)
43
44 wxAcceleratorRefData::wxAcceleratorRefData()
45 {
46 m_ok = false;
47 m_hAccel = 0;
48 } // end of wxAcceleratorRefData::wxAcceleratorRefData
49
50 wxAcceleratorRefData::~wxAcceleratorRefData()
51 {
52 if (m_hAccel)
53 {
54 WinDestroyAccelTable((HACCEL) m_hAccel);
55 }
56 m_hAccel = 0 ;
57 } // end of wxAcceleratorRefData::~wxAcceleratorRefData
58
59 wxAcceleratorTable::wxAcceleratorTable()
60 {
61 m_refData = NULL;
62 } // end of wxAcceleratorTable::wxAcceleratorTable
63
64 wxAcceleratorTable::~wxAcceleratorTable()
65 {
66 } // end of wxAcceleratorTable::~wxAcceleratorTable
67
68 // Load from .rc resource
69 wxAcceleratorTable::wxAcceleratorTable(
70 const wxString& rResource
71 )
72 {
73 HACCEL hAccel;
74 ULONG ulId;
75
76 m_refData = new wxAcceleratorRefData;
77
78 ulId = atol(rResource.c_str());
79 hAccel = ::WinLoadAccelTable( vHabmain
80 ,NULL // resources always in .exe
81 ,(ULONG)ulId
82 );
83 if (wxTheApp->GetTopWindow() != NULL)
84 {
85 //
86 // If we have accelerators the top window is the frame
87 //
88 wxFrame* pFrame = (wxFrame*)wxTheApp->GetTopWindow();
89
90 ::WinSetAccelTable( vHabmain
91 ,hAccel
92 ,(HWND)pFrame->GetFrame()
93 );
94 }
95 M_ACCELDATA->m_hAccel = hAccel;
96 M_ACCELDATA->m_ok = (hAccel != 0);
97 }
98
99 extern int wxCharCodeWXToOS2(
100 int nId
101 , bool* pbIsVirtual
102 );
103
104 // Create from an array
105 wxAcceleratorTable::wxAcceleratorTable(
106 int n
107 , const wxAcceleratorEntry vaEntries[]
108 )
109 {
110 int nAccelLength = ((sizeof(ACCEL) * n) + sizeof(ACCELTABLE));
111 PACCELTABLE pArr;
112 int i;
113
114 m_refData = new wxAcceleratorRefData;
115 pArr = (PACCELTABLE) new BYTE[nAccelLength];
116
117 for (i = 0; i < n; i++)
118 {
119 USHORT uVirt = AF_CHAR;
120
121 if (vaEntries[i].GetFlags() & wxACCEL_ALT)
122 {
123 uVirt |= AF_ALT;
124 uVirt |= AF_VIRTUALKEY;
125 }
126 if (vaEntries[i].GetFlags() & wxACCEL_SHIFT)
127 {
128 uVirt |= AF_SHIFT;
129 uVirt |= AF_VIRTUALKEY;
130 }
131 if (vaEntries[i].GetFlags() & wxACCEL_CTRL)
132 {
133 uVirt |= AF_CONTROL;
134 uVirt |= AF_VIRTUALKEY;
135 }
136
137 bool bIsVirtual;
138 USHORT uKey = (USHORT)wxCharCodeWXToOS2( vaEntries[i].GetKeyCode(),
139 &bIsVirtual);
140 if (bIsVirtual)
141 uVirt = AF_CHAR | AF_VIRTUALKEY;
142
143 USHORT uCmd = (USHORT)vaEntries[i].GetCommand();
144
145 pArr->aaccel[i].fs = uVirt;
146 pArr->aaccel[i].key = uKey;
147 pArr->aaccel[i].cmd = uCmd;
148 }
149 pArr->codepage = (USHORT)::WinQueryCp(wxTheApp->m_hMq);
150 pArr->cAccel = (USHORT)n;
151 M_ACCELDATA->m_hAccel = ::WinCreateAccelTable( vHabmain
152 ,pArr
153 );
154 if (wxTheApp->GetTopWindow() != NULL)
155 {
156 //
157 // If we have accelerators the top window is the frame
158 //
159 wxFrame* pFrame = (wxFrame*)wxTheApp->GetTopWindow();
160
161 ::WinSetAccelTable( vHabmain
162 ,M_ACCELDATA->m_hAccel
163 ,(HWND)pFrame->GetFrame()
164 );
165 }
166
167 delete[] pArr;
168 M_ACCELDATA->m_ok = (M_ACCELDATA->m_hAccel != 0);
169 } // end of wxAcceleratorTable::wxAcceleratorTable
170
171 bool wxAcceleratorTable::IsOk() const
172 {
173 return(M_ACCELDATA && (M_ACCELDATA->m_ok));
174 } // end of wxAcceleratorTable::IsOk
175
176 void wxAcceleratorTable::SetHACCEL(WXHACCEL hAccel)
177 {
178 if (!M_ACCELDATA)
179 m_refData = new wxAcceleratorRefData;
180
181 M_ACCELDATA->m_hAccel = (HACCEL) hAccel;
182 }
183
184 WXHACCEL wxAcceleratorTable::GetHACCEL() const
185 {
186 if (!M_ACCELDATA)
187 return 0;
188 return (WXHACCEL) M_ACCELDATA->m_hAccel;
189 }
190
191 bool wxAcceleratorTable::Translate( WXHWND hWnd,
192 WXMSG* pWxmsg ) const
193 {
194 PQMSG pMsg = (PQMSG)pWxmsg;
195 BOOL rc = FALSE;
196
197 rc = ::WinTranslateAccel( vHabmain
198 ,(HWND)hWnd
199 ,GetHaccel()
200 ,pMsg
201 );
202 return (IsOk() && rc);
203 } // end of wxAcceleratorTable::Translate
204
205 // ---------------------------------------------------------------------------
206 // function for translating labels
207 // ---------------------------------------------------------------------------
208
209 wxString wxPMTextToLabel( const wxString& rsTitle )
210 {
211 wxString sTitle;
212 const wxChar* zPc;
213
214 if (rsTitle.empty())
215 return(sTitle);
216
217 for (zPc = rsTitle.c_str(); *zPc != wxT('\0'); zPc++)
218 {
219 if (*zPc == wxT('&'))
220 {
221 if (*(zPc + 1) == wxT('&'))
222 {
223 zPc++;
224 sTitle << wxT('&');
225 }
226 else
227 sTitle << wxT('~');
228 }
229 else
230 {
231 if ( *zPc == wxT('~'))
232 {
233 //
234 // Tildes must be doubled to prevent them from being
235 // interpreted as accelerator character prefix by PM ???
236 //
237 sTitle << *zPc;
238 }
239 sTitle << *zPc;
240 }
241 }
242 return(sTitle);
243 } // end of wxPMTextToLabel