]> git.saurik.com Git - wxWidgets.git/blob - src/msw/colordlg.cpp
added a section about Connect(), improve/streamline the one about event tables
[wxWidgets.git] / src / msw / colordlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/colordlg.cpp
3 // Purpose: wxColourDialog class
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 01/02/97
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_COLOURDLG && !(defined(__SMARTPHONE__) && defined(__WXWINCE__))
28
29 #include "wx/colordlg.h"
30
31 #ifndef WX_PRECOMP
32 #include "wx/msw/wrapcdlg.h"
33 #include <stdio.h>
34 #include "wx/colour.h"
35 #include "wx/gdicmn.h"
36 #include "wx/utils.h"
37 #include "wx/dialog.h"
38 #include "wx/cmndata.h"
39 #include "wx/math.h"
40 #endif
41
42 #include "wx/msw/private.h"
43
44 #include <stdlib.h>
45 #include <string.h>
46
47 // ----------------------------------------------------------------------------
48 // globals
49 // ----------------------------------------------------------------------------
50
51 // standard colors dialog size for the Windows systems
52 // this is ok if color dialog created with standart color
53 // and "Define Custom Colors" extension not shown
54 static wxRect gs_rectDialog(0, 0, 222, 324);
55
56 // ----------------------------------------------------------------------------
57 // wxWin macros
58 // ----------------------------------------------------------------------------
59
60 IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog)
61
62 // ============================================================================
63 // implementation
64 // ============================================================================
65
66 // ----------------------------------------------------------------------------
67 // colour dialog hook proc
68 // ----------------------------------------------------------------------------
69
70 UINT_PTR CALLBACK
71 wxColourDialogHookProc(HWND hwnd,
72 UINT uiMsg,
73 WPARAM WXUNUSED(wParam),
74 LPARAM lParam)
75 {
76 if ( uiMsg == WM_INITDIALOG )
77 {
78 CHOOSECOLOR *pCC = (CHOOSECOLOR *)lParam;
79 wxColourDialog * const
80 dialog = wx_reinterpret_cast(wxColourDialog *, pCC->lCustData);
81
82 const wxString title = dialog->GetTitle();
83 if ( !title.empty() )
84 ::SetWindowText(hwnd, title.wx_str());
85
86 dialog->MSWOnInitDone((WXHWND)hwnd);
87 }
88
89 return 0;
90 }
91
92 // ----------------------------------------------------------------------------
93 // wxColourDialog
94 // ----------------------------------------------------------------------------
95
96 void wxColourDialog::Init()
97 {
98 m_movedWindow = false;
99 m_centreDir = 0;
100
101 // reset to zero, otherwise the wx routines won't size the window the
102 // second time the dialog is shown, because they would believe it already
103 // has the requested size/position
104 gs_rectDialog.x =
105 gs_rectDialog.y = 0;
106 }
107
108 bool wxColourDialog::Create(wxWindow *parent, wxColourData *data)
109 {
110 m_parent = parent;
111 if (data)
112 m_colourData = *data;
113
114 return true;
115 }
116
117 int wxColourDialog::ShowModal()
118 {
119 // initialize the struct used by Windows
120 CHOOSECOLOR chooseColorStruct;
121 memset(&chooseColorStruct, 0, sizeof(CHOOSECOLOR));
122
123 size_t i;
124
125 // and transfer data from m_colourData to it
126 COLORREF custColours[16];
127 for ( i = 0; i < WXSIZEOF(custColours); i++ )
128 {
129 if ( m_colourData.m_custColours[i].IsOk() )
130 custColours[i] = wxColourToRGB(m_colourData.m_custColours[i]);
131 else
132 custColours[i] = RGB(255,255,255);
133 }
134
135 chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR);
136 if ( m_parent )
137 chooseColorStruct.hwndOwner = GetHwndOf(m_parent);
138 chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.m_dataColour);
139 chooseColorStruct.lpCustColors = custColours;
140
141 chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK;
142 chooseColorStruct.lCustData = (LPARAM)this;
143 chooseColorStruct.lpfnHook = wxColourDialogHookProc;
144
145 if ( m_colourData.GetChooseFull() )
146 chooseColorStruct.Flags |= CC_FULLOPEN;
147
148 // do show the modal dialog
149 if ( !::ChooseColor(&chooseColorStruct) )
150 {
151 // 0 error means the dialog was simply cancelled, i.e. no real error
152 // occurred
153 const DWORD err = CommDlgExtendedError();
154 if ( err )
155 wxLogError(_("Colour selection dialog failed with error %0lx."), err);
156
157 return wxID_CANCEL;
158 }
159
160
161 // transfer the values chosen by user back into m_colourData
162 for ( i = 0; i < WXSIZEOF(custColours); i++ )
163 {
164 wxRGBToColour(m_colourData.m_custColours[i], custColours[i]);
165 }
166
167 wxRGBToColour(m_colourData.m_dataColour, chooseColorStruct.rgbResult);
168
169 // this doesn't seem to work (contrary to what MSDN implies) on current
170 // Windows versions: CC_FULLOPEN is never set on return if it wasn't
171 // initially set and vice versa
172 //m_colourData.SetChooseFull((chooseColorStruct.Flags & CC_FULLOPEN) != 0);
173
174 return wxID_OK;
175 }
176
177 // ----------------------------------------------------------------------------
178 // title
179 // ----------------------------------------------------------------------------
180
181 void wxColourDialog::SetTitle(const wxString& title)
182 {
183 m_title = title;
184 }
185
186 wxString wxColourDialog::GetTitle() const
187 {
188 return m_title;
189 }
190
191 // ----------------------------------------------------------------------------
192 // position/size
193 // ----------------------------------------------------------------------------
194
195 void wxColourDialog::DoGetPosition(int *x, int *y) const
196 {
197 if ( x )
198 *x = gs_rectDialog.x;
199 if ( y )
200 *y = gs_rectDialog.y;
201 }
202
203 void wxColourDialog::DoCentre(int dir)
204 {
205 m_centreDir = dir;
206
207 // it's unnecessary to do anything else at this stage as we'll redo it in
208 // MSWOnInitDone() anyhow
209 }
210
211 void wxColourDialog::DoMoveWindow(int x, int y, int WXUNUSED(w), int WXUNUSED(h))
212 {
213 gs_rectDialog.x = x;
214 gs_rectDialog.y = y;
215
216 // our HWND is only set when we're called from MSWOnInitDone(), test if
217 // this is the case
218 HWND hwnd = GetHwnd();
219 if ( hwnd )
220 {
221 // size of the dialog can't be changed because the controls are not
222 // laid out correctly then
223 ::SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
224 }
225 else // just remember that we were requested to move the window
226 {
227 m_movedWindow = true;
228
229 // if Centre() had been called before, it shouldn't be taken into
230 // account now
231 m_centreDir = 0;
232 }
233 }
234
235 void wxColourDialog::DoGetSize(int *width, int *height) const
236 {
237 if ( width )
238 *width = gs_rectDialog.width;
239 if ( height )
240 *height = gs_rectDialog.height;
241 }
242
243 void wxColourDialog::DoGetClientSize(int *width, int *height) const
244 {
245 if ( width )
246 *width = gs_rectDialog.width;
247 if ( height )
248 *height = gs_rectDialog.height;
249 }
250
251 void wxColourDialog::MSWOnInitDone(WXHWND hDlg)
252 {
253 // set HWND so that our DoMoveWindow() works correctly
254 SetHWND(hDlg);
255
256 if ( m_centreDir )
257 {
258 // now we have the real dialog size, remember it
259 RECT rect;
260 ::GetWindowRect((HWND)hDlg, &rect);
261 gs_rectDialog = wxRectFromRECT(rect);
262
263 // and position the window correctly: notice that we must use the base
264 // class version as our own doesn't do anything except setting flags
265 wxDialog::DoCentre(m_centreDir);
266 }
267 else if ( m_movedWindow ) // need to just move it to the correct place
268 {
269 SetPosition(GetPosition());
270 }
271
272 // we shouldn't destroy hDlg, so disassociate from it
273 SetHWND(NULL);
274 }
275
276 #endif // wxUSE_COLOURDLG && !(__SMARTPHONE__ && __WXWINCE__)