|
|
If I only used the "Automatic" button (default color) button to select my color, the value returned by the DDX function was always -2 (CLR_DEFAULT). I had to add a check for CLR_DEFAULT so the default color can be returned. The modified function is:
void AFXAPI DDX_ColorButton(CDataExchange *pDX, int nIDC, COLORREF& crColour)<br />
{<br />
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);<br />
ASSERT (hWndCtrl != NULL); <br />
<br />
CColorButton* pColourButton = (CColorButton*) CWnd::FromHandle(hWndCtrl);<br />
if (pDX->m_bSaveAndValidate)<br />
{<br />
if (pColourButton->Color == CLR_DEFAULT)<br />
crColour = pColourButton->DefaultColor;<br />
else<br />
crColour = pColourButton->Color;<br />
}<br />
else
{<br />
pColourButton->Color = crColour;<br />
}<br />
}
|
|
|
|
|
First, thanks for an excellent and useful article.
I'm using it in a resizable dialog, and moving the buttons using SetWindowPos(). But I notice that after I do this, the Color Picker stops responding to clicks and does not call the OnClicked() method.
|
|
|
|
|
Hmmm.. It has been a very long time since I've looked at this, but what you are seeing could indicate that the control has cached its rectangle for responding to clicks and for whatever reason isn't updating it when you call SetWindowPos(). You might try checking the source code to see if when responding to MouseOver events, the control uses a rectangle that it has stored from before, or whether it is using GetWindowRect. If it is the former, perhaps that is the source of the bug.
Good luck!
James
|
|
|
|
|
Thanks for the reply, James. Turns out it wasn't the Color Picker button after all. I was using a toolbar at the bottom of the screen in the same line as the Color Picker buttons and had this:
<br />
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);<br />
which by default stretches the toolbar. This was fixed by changing it to this:
<br />
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0, CWnd::reposDefault, NULL, NULL, FALSE);<br />
|
|
|
|
|
Hi,
I is not figure what is TrackSelection. Can you explaining this?
Thank you. You have great moustache!
|
|
|
|
|
I believe (though it has been a while) that the idea of this is to track the color the user is hovering over for display in the button or another panel.
|
|
|
|
|
I'm being sorrowful, but is not comprehend of what this meaning. What is this tracking color. Where is it tracked and what is doing with this.
Thank you with flipping toes.
|
|
|
|
|
I think it means that when you move your mouse over the colors on the control, they show up in the color square on the control. So when a user moves over red, the control shows red on the button, and when the user moves their mouse over blue, the control shows blue. Best of luck!
|
|
|
|
|
James,
thanks for great job.
When the user clicks on 'Automatic' button what message should be handled
to retrieve the Default color from the control ?
thanks in advance
-Simon
|
|
|
|
|
Hi,
your control is very usefull and pretty. But I have a problem, maybe it belongs to the use I made of it, I don't know how to fix it.
I use this color button control in a "tool/preference" menu page. I have construct a CArray of CColor like this:
CArray<CColor, CColor&> CColorArray;
and its use is perfect in my project, I also read/write the values in a database, upon reading, it shows the right color, so manipulation intro my variable and/or DB is not a problem. I use m_colorButn.SetColor(myCColorvalue) to set the color from my settings, it sets right, but when I set it for another button (in the same page obviously), the previous button change for a dummy color! always! this way I can't use it for many buttons.
is that a problem with the control itself or the way I have implemente it? it is linked this way in the dodataexhange:
DDX_Control(pDX, IDC_BTN_CLR_TITLE_FONT, m_buttonColorTitleFont);
and so on for all the different buttons.
then
COLORREF ThrowAwayColorTitleFont;
DDX_ColorButton(pDX, IDC_BTN_CLR_TITLE_FONT, ThrowAwayColorTitleFont);
and so on (there is a different throawaycolor variable for each IDC_BTN_).
in the .h, it is a CColorButton, and I do have implemented the OnSelEndOK, OnSelEndCancel, OnSelChange, OnCloseUp, OnDropDown methods
Mathieu
|
|
|
|
|
Mathieu,
I tried setting the color for multiple buttons on the same page in the demonstration app and didn't see a similar result. It has been a while since I have looked at this code though, so I could be overlooking something obvious. One thing I might try is just removing the 'ThrowAwayColor' section as I am uncertain of its value and it could conceivably be setting the color when you don't intend it to. I might be mistaken, but it seems unnecessary. I also might put a breakpoint in code that changes m_Color in the class and try to catch any code that sets it to the wrong color. Let me know what you find.
Thanks!
James
|
|
|
|
|
Hello,
The problem is actually existent. I have a CListCtrl taht contains many items. Let say I have one CColorButton for a particular parameter. For every item in the CListCtrl, I have a parameter, say the font color, and I want to use the same controlbutton as I don't know how many items there is in the CClistCtrl (and there is so many other parameters, so I have a limited visual space). So I have build a CArray of CColor that contains an identical number of members as there is members in the CListCtrl. So when I click on an item in the CListCtrl, I want the CColorButton to show the color of the particular item in the control list. But it does not, it shows the last color selected always.
the code is as follow
//.h file
public:
//{{AFX_DATA(CSettingFormChart)
CColorButton m_buttonColorLine;
//}}AFX_DATA
typedef CArray<CColor, CColor&> CColorArray; //actually this is in another file...
CColorArray a_colorLine;
int m_item_selected; //when the user select an item in the CListCtrl, this handle the index of teh selection, which is in the same order as the index of the a_colorLine Array.
//.cpp file:
void CSettingFormChart::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSettingFormChart)
DDX_Control(pDX, IDC_BTN_CLR_LINE, m_buttonColorLine);
//}}AFX_DATA_MAP
COLORREF ThrowAwayColor;
DDX_ColorButton(pDX, IDC_BTN_CLR_LINE, ThrowAwayColor);
}
BEGIN_MESSAGE_MAP ...// for OnSelEndOK, OnSelEndCancel, OnSelChange, OnCloseUp, OnDropDown
//then on the OnSelEndOK, notice my method
LONG CSettingFormChart::OnSelEndOK(UINT /*lParam*/, LONG /*wParam*/)
{ TRACE0("Selection ended OK\n");
UpdateColorAfterSelection();
return TRUE;
}
void CSettingFormChart::UpdateColorAfterSelection()
{
a_colorLine.SetAt(m_item_selected, m_buttonColorLine.Color) ; // here m_item_selected correspond to the actual selection in the ListCtrl, I have checked. The color is also correct
}
//then on cnaging item selection on the list:
void CSettingFormChart::OnItemchangedListSettchartPlotarea(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; //normal thing
POSITION pos = m_list.GetFirstSelectedItemPosition();
if (pos)
{//there is a valid selection
int nItem = m_list.GetNextSelectedItem(pos); //this gives back the actual index selected in the list
m_item_selected = nItem;
m_buttonColorLine.SetColor(a_colorLine.ElementAt(m_item_selected); //or GetAt, I have tested
}//was a valid selection
}
so I don't understand the problem...
thank you
Mathieu
|
|
|
|
|
ok, I have just take out the
DDX_ColorButton(pDX, IDC_BTN_CLR_LINE, ThrowAwayColor);
line in the DoDataExchange and that's very very very fine!
However, can you assure me there is no memory leak by taking out this command?
This was orinigally setup for a valid reason by the first programmer, so it might cause problems in extensive use, am I right?
Mathieu
|
|
|
|
|
I'm uncertain. The lines that were removed just set/get the color of the controls, so I can't imagine why that should be necessary if you are doing it in another manner. Obviously there was some reason behind those lines, but you should be able to see any leaks when the application shuts down, so if there isn't a change there you should be good.
|
|
|
|
|
Do you have any suggestions for adding a button like this to a CToolBar or CToolBarCtrl?
Mike
http://www.elkriversystems.com
|
|
|
|
|
I've been using this excellent control in one of my freeware apps, but I recently realized that this control has a potentially serious problem. In automating Internet Explorer, I had to include the system header file afxctl.h (for the AfxConnectionAdvise() and AfxConnectionUnadvise() methods). Upon trying to compile, I get a notification that the CColorButton class has been redefined.
The problem seems that a CColorButton class already exists in the aforementioned header file. This control is part of the common color choosing property page in Windows. To correct the solution, I simply renamed all instances of CColorButton in this control (by James White) to JWCColorButton . This remedied the problem for me.
I suggest that the name of this class be changed for future usage, since it conflicts with a class already supplied by MFC. Otherwise, this is an excellent resource!
Jonah Bishop
Visit JGB Productions
|
|
|
|
|
That's a very good idea. I think I've run into similar problems prompting me to wrap it in a namespace for our apps. The original 'picker' control used the British "Colour" which I should have just preserved, has a quaint timeless quality to it.
|
|
|
|
|
James White wrote:
the British "Colour" which I should have just preserved, has a quaint timeless quality to it.
Not sure about 'quaint', but it's definately timeless; we were using it before you Americans were even invented
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
And sadly we'll be using its bastardized form long after the "ever closer union" imposes French on our old homeland.
|
|
|
|
|
très drôle mon ami!
"The way of a fool seems right to him, but a wise man listens to advice" - Proverbs 12:15 (NIV)
|
|
|
|
|
Hello, I used this good control in dialog and I have two problems.
In one case when I click out of popup window but in dialog, it won't lose a focus. I'm using it in dialog, which is modal.
But in the second case I'm using it in docked window, in something like property editor. When I click into docked property editor, focus is lost, but when i clinc on application main window, focus is still here. Do you have any suggestions?
Thanks for helping. Petr K.
|
|
|
|
|
I have the same problem, any assistance would be great!
Thanks,
Dave
|
|
|
|
|
First of all great work (to you and Chris). Very useful control, thanks.
Secondly the problem. I have used the control in two different places, one in a page in an SAPrefs dialog. The other in a tab page for CTabCtrlSSL (my own). Essentially these are both the same as they behave like property sheets.
However, when used in the SAPrefs page a single click is required to select a colour and then the popup is removed as expected. In the tab page, after the first click the colour is changed and the CPN_SELENDOK message is received by the parent, but a second click is required to remove the colour popup.
In both instances the buttons are created using DDX_Control and the colour updating is done via DDX_ColorButton in DoDataExchange.
Any ideas?
Derek Lakin.
I wish I was what I thought I was when I wished I was what I am.
Salamander Software Ltd.
|
|
|
|
|
Derek,
I'm actually a bit fuzzy at the moment (big deadline in the morning ) but at first glance I'd say the problem is related to the 'm_bChildWindowVisible' flag in the CoulourPopup source. When that flag is true, the window will not be destroyed. Perhaps if you placed a breakpoint there in the first click you could verify this. I will try to track down the problem as soon as I come up for air, but let me know if you find anything interesting.
Thanks,
James
|
|
|
|
|