|
First, thanks for your program.
But this Program is not working at VS 2008.
What is the reason?
|
|
|
|
|
Hi,
Probably you're developing on WinXP.
Edit targetver.h and set versions to 0x0500. That helped in my case, working fine now.
Gy
|
|
|
|
|
There are a couple of warnings when compiling with level 4 in Visual Studio 2003:
ColourPickerXP.cpp(683) : warning C4100: 'pNMHDR' : unreferenced formal parameter
ColourPickerXP.cpp(724) : warning C4100: 'lParam' : unreferenced formal parameter
ColourPickerXP.cpp(724) : warning C4100: 'wParam' : unreferenced formal parameter
ColourPickerXP.cpp(1866) : warning C4245: '=' : conversion from 'int' to 'COLORREF', signed/unsigned mismatch
colourpickerxp.cpp(2071) : warning C4701: local variable 'clr3dTopLeft' may be used without having been initialized
colourpickerxp.cpp(2071) : warning C4701: local variable 'clr3dBottomRight' may be used without having been initialized
I'm going to fix them up, but it would be great if you would update the code for others.
|
|
|
|
|
Hi there,
thanks for the nice control. one small issue, if on left or top secondary monitor, the point needs to be (short) to be cast to signed value (negative).
REPLACE THIS:
// End selection on LButtonUp
void CColourPopupXP::OnLButtonUp(UINT nFlags, CPoint point)
{
CWnd::OnLButtonUp(nFlags, point);
DWORD pos = GetMessagePos();
point = CPoint(LOWORD(pos), HIWORD(pos));
if (m_WindowRect.PtInRect(point))
EndSelection(CPN_SELENDOK);
else
EndSelection(CPN_SELENDCANCEL);
}
WITH THIS:
// End selection on LButtonUp
void CColourPopupXP::OnLButtonUp(UINT nFlags, CPoint point)
{
CWnd::OnLButtonUp(nFlags, point);
DWORD pos = GetMessagePos();
point = CPoint((short)LOWORD(pos), (short)HIWORD(pos));
if (m_WindowRect.PtInRect(point))
EndSelection(CPN_SELENDOK);
else
EndSelection(CPN_SELENDCANCEL);
}
|
|
|
|
|
This fix works for me only if I also modify CColourPopupXP::SetWindowSize().
Around line 1800 :
// Need to check it'll fit on screen: Too far right?
if (m_WindowRect.right > ScreenSize.cx)
m_WindowRect.OffsetRect(-(m_WindowRect.right - ScreenSize.cx), 0);
// Too far left?
if (m_WindowRect.left < 0)
m_WindowRect.OffsetRect( -m_WindowRect.left, 0);
// Bottom falling out of screen?
if (m_WindowRect.bottom > ScreenSize.cy)
{
CRect ParentRect;
m_pParent->GetWindowRect(ParentRect);
m_WindowRect.OffsetRect(0, -(ParentRect.Height() + m_WindowRect.Height()));
}
This code is directly above the call to MoveWindow(). If this code isn't commented out the colorpopup will display on the left edge of the right monitor when the program is run on the left monitor.
|
|
|
|
|
is it possible to get the value of the COLORREF, and how can I display it as a messagebox
something like
MessageBox(COLORREF);
thanks in advance
|
|
|
|
|
Hi Zorglab
1 - Very NICE class. My vote is 5.
2 - Notice: Using custom message(WM_USER+???) is useful.
But when develop an class, do NOT define custom message in your class,
if your class will direct that custom message to third party windows.
Define custom message as variable and ask programmer to set it.
This rule, prevent conflicting of your message by other custom message in third party application.
3 - Your class can let to his parent, to trap click command of drived class.
So parent does NOT need to traps custom message.
Simply, in design time, double click on button and add MFC wizard suggested function.
By this technigue, CColourPickerXP will became "HOT Plug and Play"!
ToDo: Change your code as following:
BOOL CColourPickerXP::OnClicked()<br />
{<br />
<br />
CRect rDraw;<br />
GetWindowRect(rDraw);<br />
<br />
DWORD pos = GetMessagePos();<br />
CPoint point = CPoint(LOWORD(pos), HIWORD(pos));<br />
if(! rDraw.PtInRect(point))<br />
return FALSE;<br />
<br />
m_bPopupActive = TRUE;<br />
....
and in next step ...
LONG CColourPickerXP::OnSelEndOK(UINT lParam, LONG )<br />
{<br />
m_bPopupActive = FALSE;<br />
COLORREF OldColor = m_Color;<br />
Color = (COLORREF)lParam;<br />
CWnd *pParent = GetParent();<br />
<br />
if (pParent) <br />
{<br />
pParent->SendMessage(CPN_CLOSEUP, lParam, (WPARAM) GetDlgCtrlID());<br />
pParent->SendMessage(CPN_SELENDOK, lParam, (WPARAM) GetDlgCtrlID());<br />
}<br />
<br />
if (OldColor != m_Color)<br />
if (pParent)<br />
{<br />
pParent->SendMessage(CPN_SELCHANGE, m_Color, (WPARAM) GetDlgCtrlID());<br />
<br />
pParent->PostMessage(WM_COMMAND,<br />
MAKEWPARAM( GetDlgCtrlID(), BN_CLICKED), (LPARAM)this->m_hWnd );<br />
}<br />
<br />
return TRUE;<br />
}
You can dowload modified class with an example from here --> [N/A]
|
|
|
|
|
Well, Joseph Newcomer will agree with you.
If one understands the correct use of the different 'bands' of WM's then one does not get into strife:
< WM_USER = windows specific - use as documented - Windows private messages
WM_USER to WM_APP for windows controls - Control Private Messages
>= WM_APP for Control containers IE programmer created windows - Application private messages
(some control messages are within the windows private range).
Because [sometimes] communications with child controls (EG edit etc.) is with the shared band between WM_USER and WM_APP there is no conflict as the message is being sent to a specific child window that handles that message.
The troubles come in when ordinary windows (control owners) use the band between WM_USER and WM_APP for windows messages private to the application - sometimes they conflict with messages preallocated for child windows and get to the child windows raising nasty bugs. So, as is well known, use WM_APP > for your own application private messages.
There are other bands of messages - one for OLE and another for registered windows messages. Joseph Newcomer advocates always and only ever using registered messages with names derived from guids (I believe) - see his web site for details. Others agree that if you stick by the rules you will not run into strife.
|
|
|
|
|
I wrote:
...
2 - Notice: Using custom message(WM_USER+???) is useful.
But when develop an class, do NOT define custom message in your class,
if your class will direct that custom message to third party windows.
Define custom message as variable and ask programmer to set it.
This rule, prevent conflicting of your message by other custom message in third party application.
...
In other hand:
Suppose you have 2 class. CTPClass1 and CTPClass2; and them want to send their custom message to its parent. The first class use (WM_USER+1) and also second class use (WM_USER+1) to send custom message.
Now, when parent receives an message with id=(WM_USER+1), how can it detect which type of child sent that message!?
|
|
|
|
|
In a multi-monitor scenario, if the color picker button in on a non-primary monitor, the drop downpop up window appears on the primary monitor, rather than where it should be.
I'm working up a solution for my needs. If you're interesed I can forward it to you when I'm done. (It is going to rely on a couple of additional class).
|
|
|
|
|
Using the multimonitor classes, or the conditionally compiled code present in CColourPopupXP::SetWindowSize , replace the logic that does the resisng at the end of that method with this:
CMonitor monitor = CMonitors::GetNearestMonitor( this );
CRect monitorRect;
monitor.GetWorkAreaRect( &monitorRect );
if (m_WindowRect.right > monitorRect.right)
m_WindowRect.OffsetRect( -m_WindowRect.Width(), 0 );
if (m_WindowRect.left < monitorRect.left)
m_WindowRect.OffsetRect( monitorRect.left - m_WindowRect.left, 0 );
if (m_WindowRect.bottom > monitorRect.bottom)
{
CRect ParentRect;
m_pParent->GetWindowRect(ParentRect);
m_WindowRect.OffsetRect( 0, -(ParentRect.Height() + m_WindowRect.Height()) );
}
where monitorRect is the rectangle of the monitor that the window is being displayed on.
|
|
|
|
|
Well done. This is a very nice control.
If you don't mind, I'd like to use it in my Clock Screen saver (another project here on CodeProject)
|
|
|
|
|
Thanks.
You may use my control freely for any non-commercial purpose you want. If you want to use it in a commercial application, just send me a mail (so I can see where this control is good for ).
|
|
|
|
|
5/5 ;P
Cheers, Sanjit
|
|
|
|
|
The two calls to strcpy on lines #434 and #440 of ColourPickerXP.cpp should be changed to _tcscpy .
|
|
|
|
|
unlurk...
This is probably nitpicking, but I noticed that the control has some redraw problem when it is over the IE favorites explorer bar or over an application that is using WS_EX_LAYERED (Winamp + TransparentFX). (fyi, I wrote TransparentFX)
Great coding though!
back to lurking...
|
|
|
|
|
Hi
Did you ever find a solution please to the above problem.
Thanks
Terry
|
|
|
|
|
Try to comment the following line in the CColourPopupXP::Create method
pTopParent->SetRedraw( FALSE );
|
|
|
|
|
Wow, that was as easy as saying 1-2-3.
Good job!
Toc ![Smile | :)](https://cdn.statically.io/img/www.codeproject.com/script/Forums/Images/smiley_smile.gif)
|
|
|
|
|
Thanks ![Smile | :)](https://cdn.statically.io/img/www.codeproject.com/script/Forums/Images/smiley_smile.gif)
|
|
|
|
|
Hi!
- click a arrow;
- select a "More colours...";
- unhide, hide, unhide, hide and so on a "colour popup" window by draging a "color dialog" in any direction;
- you'll see an error "A required resource was" (on WinMe).
Solution:
void CColourPopupXP::DrawCell(CDC* pDC, int nIndex)<br />
{<br />
...<br />
if (bSelected)<br />
{<br />
...<br />
pDC->SelectObject(pOldBrush);<br />
pDC->SelectObject(pOldPen);<br />
}<br />
...<br />
if (szText != _T(""))<br />
{<br />
...<br />
}<br />
else<br />
{<br />
...<br />
pDC->SelectObject(pOldBrush);<br />
pDC->SelectObject(pOldPen);<br />
}<br />
...<br />
}
Sincerely Yours,
Kris Wojtas
|
|
|
|
|
Thanks for this bug report. I still don't understand how I managed to make such a big mistake.
It'll be fixed in version 1.4.
|
|
|
|
|
this class is similiar with CColorPicker in CJLib writen by CodeJock.com.
Is it you or codejock get inspiration from the opposite one? or it is your own masterpiece?
anyway , your class is very good,i like it!
|
|
|
|
|
Maybe the colour picker on CodeJock.com is also based on Chris Maunder's, but I haven't used other ideas than the ones specified in the Acknowledgments section.
Anyway, thanks ![Big Grin | :-D](https://cdn.statically.io/img/www.codeproject.com/script/Forums/Images/smiley_biggrin.gif)
|
|
|
|
|
Although I set the TrackSelection to false, my dialog receives CPN_SELCHANGE (with the old color value) every time the mouse move over a color cell, causing other components flickering becouse they are repainted with the current color.
To avoid this problem, can be usefull to change the function:
LONG CColourPickerXP::OnSelChange(UINT lParam, LONG /*wParam*/)
{
if (m_bTrackSelection)
Color = (COLORREF)lParam;
CWnd *pParent = GetParent();
if (pParent) pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
return TRUE;
}
To something similar, sending the message only if the color is effectively changed:
LONG CColourPickerXP::OnSelChange(UINT lParam, LONG /*wParam*/)
{
if (m_bTrackSelection) {
COLORREF OldColor = m_Color;
Color = (COLORREF)lParam;
CWnd *pParent = GetParent();
if (pParent && OldColor != m_Color)
pParent->SendMessage(CPN_SELCHANGE, lParam, (WPARAM) GetDlgCtrlID());
}
return TRUE;
}
|
|
|
|