X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ad81651f00edc6f489d9b6a0839d316a964fd521..5a0b1008ff8e3e20ed2219172bf000844c6e91e4:/src/msw/colordlg.cpp diff --git a/src/msw/colordlg.cpp b/src/msw/colordlg.cpp index 66e0a3ef73..5994521841 100644 --- a/src/msw/colordlg.cpp +++ b/src/msw/colordlg.cpp @@ -1,124 +1,276 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: colordlg.cpp +// Name: src/msw/colordlg.cpp // Purpose: wxColourDialog class // Author: Julian Smart // Modified by: // Created: 01/02/97 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Copyright: (c) Julian Smart +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "colordlg.h" -#endif +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif -#ifndef WX_PRECOMP -#include -#include "wx/defs.h" -#include "wx/bitmap.h" -#include "wx/pen.h" -#include "wx/brush.h" -#include "wx/colour.h" -#include "wx/gdicmn.h" -#include "wx/utils.h" -#include "wx/frame.h" -#include "wx/dialog.h" -#include "wx/msgdlg.h" -#endif +#if wxUSE_COLOURDLG && !(defined(__SMARTPHONE__) && defined(__WXWINCE__)) -#include +#include "wx/colordlg.h" -#if !defined(__WIN32__) || defined(__SALFORDC__) || defined(__WXWINE__) -#include +#ifndef WX_PRECOMP + #include "wx/msw/wrapcdlg.h" + #include + #include "wx/colour.h" + #include "wx/gdicmn.h" + #include "wx/utils.h" + #include "wx/dialog.h" + #include "wx/cmndata.h" + #include "wx/math.h" #endif #include "wx/msw/private.h" -#include "wx/colordlg.h" -#include "wx/cmndata.h" -#include #include #include -#define wxDIALOG_DEFAULT_X 300 -#define wxDIALOG_DEFAULT_Y 300 +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- + +// standard colors dialog size for the Windows systems +// this is ok if color dialog created with standart color +// and "Define Custom Colors" extension not shown +static wxRect gs_rectDialog(0, 0, 222, 324); + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog) -/* - * wxColourDialog - */ +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// colour dialog hook proc +// ---------------------------------------------------------------------------- -wxColourDialog::wxColourDialog(void) +UINT_PTR CALLBACK +wxColourDialogHookProc(HWND hwnd, + UINT uiMsg, + WPARAM WXUNUSED(wParam), + LPARAM lParam) { - m_dialogParent = NULL; + if ( uiMsg == WM_INITDIALOG ) + { + CHOOSECOLOR *pCC = (CHOOSECOLOR *)lParam; + wxColourDialog * const + dialog = wx_reinterpret_cast(wxColourDialog *, pCC->lCustData); + + const wxString title = dialog->GetTitle(); + if ( !title.empty() ) + ::SetWindowText(hwnd, title.wx_str()); + + dialog->MSWOnInitDone((WXHWND)hwnd); + } + + return 0; } -wxColourDialog::wxColourDialog(wxWindow *parent, wxColourData *data) +// ---------------------------------------------------------------------------- +// wxColourDialog +// ---------------------------------------------------------------------------- + +void wxColourDialog::Init() { - Create(parent, data); + m_movedWindow = false; + m_centreDir = 0; + + // reset to zero, otherwise the wx routines won't size the window the + // second time the dialog is shown, because they would believe it already + // has the requested size/position + gs_rectDialog.x = + gs_rectDialog.y = 0; } bool wxColourDialog::Create(wxWindow *parent, wxColourData *data) { - m_dialogParent = parent; + m_parent = parent; + if (data) + m_colourData = *data; - if (data) - m_colourData = *data; - return TRUE; + return true; } -int wxColourDialog::ShowModal(void) +int wxColourDialog::ShowModal() { + // initialize the struct used by Windows CHOOSECOLOR chooseColorStruct; - COLORREF custColours[16]; memset(&chooseColorStruct, 0, sizeof(CHOOSECOLOR)); - int i; - for (i = 0; i < 16; i++) - custColours[i] = RGB(m_colourData.custColours[i].Red(), m_colourData.custColours[i].Green(), m_colourData.custColours[i].Blue()); + size_t i; + + // and transfer data from m_colourData to it + COLORREF custColours[16]; + for ( i = 0; i < WXSIZEOF(custColours); i++ ) + { + if ( m_colourData.m_custColours[i].IsOk() ) + custColours[i] = wxColourToRGB(m_colourData.m_custColours[i]); + else + custColours[i] = RGB(255,255,255); + } chooseColorStruct.lStructSize = sizeof(CHOOSECOLOR); - chooseColorStruct.hwndOwner = (HWND) (m_dialogParent ? (HWND) m_dialogParent->GetHWND() : (HWND) NULL); - chooseColorStruct.rgbResult = RGB(m_colourData.dataColour.Red(), m_colourData.dataColour.Green(), m_colourData.dataColour.Blue()); + if ( m_parent ) + chooseColorStruct.hwndOwner = GetHwndOf(m_parent); + chooseColorStruct.rgbResult = wxColourToRGB(m_colourData.m_dataColour); chooseColorStruct.lpCustColors = custColours; - chooseColorStruct.Flags = CC_RGBINIT; + chooseColorStruct.Flags = CC_RGBINIT | CC_ENABLEHOOK; + chooseColorStruct.lCustData = (LPARAM)this; + chooseColorStruct.lpfnHook = wxColourDialogHookProc; + + if ( m_colourData.GetChooseFull() ) + chooseColorStruct.Flags |= CC_FULLOPEN; + + // do show the modal dialog + if ( !::ChooseColor(&chooseColorStruct) ) + { + // 0 error means the dialog was simply cancelled, i.e. no real error + // occurred + const DWORD err = CommDlgExtendedError(); + if ( err ) + wxLogError(_("Colour selection dialog failed with error %0lx."), err); - if (!m_colourData.GetChooseFull()) - chooseColorStruct.Flags |= CC_PREVENTFULLOPEN; + return wxID_CANCEL; + } - // Do the modal dialog - bool success = (ChooseColor(&(chooseColorStruct)) != 0); - // Try to highlight the correct window (the parent) - HWND hWndParent = 0; - if (GetParent()) + // transfer the values chosen by user back into m_colourData + for ( i = 0; i < WXSIZEOF(custColours); i++ ) { - hWndParent = (HWND) GetParent()->GetHWND(); - if (hWndParent) - ::BringWindowToTop(hWndParent); + wxRGBToColour(m_colourData.m_custColours[i], custColours[i]); } + wxRGBToColour(m_colourData.m_dataColour, chooseColorStruct.rgbResult); + + // this doesn't seem to work (contrary to what MSDN implies) on current + // Windows versions: CC_FULLOPEN is never set on return if it wasn't + // initially set and vice versa + //m_colourData.SetChooseFull((chooseColorStruct.Flags & CC_FULLOPEN) != 0); + + return wxID_OK; +} + +// ---------------------------------------------------------------------------- +// title +// ---------------------------------------------------------------------------- - // Restore values - for (i = 0; i < 16; i++) +void wxColourDialog::SetTitle(const wxString& title) +{ + m_title = title; +} + +wxString wxColourDialog::GetTitle() const +{ + return m_title; +} + +// ---------------------------------------------------------------------------- +// position/size +// ---------------------------------------------------------------------------- + +void wxColourDialog::DoGetPosition(int *x, int *y) const +{ + if ( x ) + *x = gs_rectDialog.x; + if ( y ) + *y = gs_rectDialog.y; +} + +void wxColourDialog::DoCentre(int dir) +{ + m_centreDir = dir; + + // it's unnecessary to do anything else at this stage as we'll redo it in + // MSWOnInitDone() anyhow +} + +void wxColourDialog::DoMoveWindow(int x, int y, int WXUNUSED(w), int WXUNUSED(h)) +{ + gs_rectDialog.x = x; + gs_rectDialog.y = y; + + // our HWND is only set when we're called from MSWOnInitDone(), test if + // this is the case + HWND hwnd = GetHwnd(); + if ( hwnd ) { - m_colourData.custColours[i].Set(GetRValue(custColours[i]), GetGValue(custColours[i]), - GetBValue(custColours[i])); + // size of the dialog can't be changed because the controls are not + // laid out correctly then + ::SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); } + else // just remember that we were requested to move the window + { + m_movedWindow = true; - m_colourData.dataColour.Set(GetRValue(chooseColorStruct.rgbResult), GetGValue(chooseColorStruct.rgbResult), - GetBValue(chooseColorStruct.rgbResult)); + // if Centre() had been called before, it shouldn't be taken into + // account now + m_centreDir = 0; + } +} + +void wxColourDialog::DoGetSize(int *width, int *height) const +{ + if ( width ) + *width = gs_rectDialog.width; + if ( height ) + *height = gs_rectDialog.height; +} + +void wxColourDialog::DoGetClientSize(int *width, int *height) const +{ + if ( width ) + *width = gs_rectDialog.width; + if ( height ) + *height = gs_rectDialog.height; +} + +void wxColourDialog::MSWOnInitDone(WXHWND hDlg) +{ + // set HWND so that our DoMoveWindow() works correctly + SetHWND(hDlg); + + if ( m_centreDir ) + { + // now we have the real dialog size, remember it + RECT rect; + ::GetWindowRect((HWND)hDlg, &rect); + gs_rectDialog = wxRectFromRECT(rect); + + // and position the window correctly: notice that we must use the base + // class version as our own doesn't do anything except setting flags + wxDialog::DoCentre(m_centreDir); + } + else if ( m_movedWindow ) // need to just move it to the correct place + { + SetPosition(GetPosition()); + } - return success ? wxID_OK : wxID_CANCEL; + // we shouldn't destroy hDlg, so disassociate from it + SetHWND(NULL); } +#endif // wxUSE_COLOURDLG && !(__SMARTPHONE__ && __WXWINCE__)