|
My dialog have 10-20 "CxSkinButton" buttons
And some buttons does now draw text!
In debug version - it's ok
But in release - there are no text on the buttons!
Can anyone help me?
ps Compiled with VC++ 6.0, Windows 98 SE
|
|
|
|
|
In xSkinButton.cpp, line 311, change the code as follows:
< dcBmp.SelectObject(hBmp);
> HBITMAP hOldBitmap = (HBITMAP)dcBmp.SelectObject(hBmp);
Then add the following line 356 (just before dcBmp.DeleteDC()):
dcBmp.SelectObject( hOldBitmap );
Otherwise, you will be deleting the DC with the bitmap still selected.
Steve
|
|
|
|
|
There are many other places where SelectObject() needs to store the return value and then select the old object before calling DeleteDC(). Here are a few, but it's best if you simply search for all calls to SelectObject() and DeleteDC().
For example, SelectObject() calls near lines 198, 202, and 207 need to be changed so they store the return value. For example:
HBITMAP hOldBitmap1 = (HBITMAP)hdcMem.SelectObject(hBitmap);
Then you need to deselect the old bitmap just before the calls to DeleteDC() (near lines 225, 228, and 243) by adding code similar to:
hdcMem.SelectObject( hOldBitmap1 );
Steve
|
|
|
|
|
There is still at least one other GDI leak in the SetSkin() method assuming that one will set the skin more than once:
Change the the follwing lines in CxSkinButton::SetSkin(...):
SetWindowRgn(m_hClipRgn, TRUE);
SelectClipRgn((HDC) GetDC(),m_hClipRgn);
to:
SetWindowRgn(m_hClipRgn, TRUE);
CDC *pDC = GetDC();
SelectClipRgn(pDC->GetSafeHdc(), m_hClipRgn);
ReleaseDC(pDC);
to ensure, that the DC is properly released.
modified on Friday, December 19, 2008 3:08 AM
|
|
|
|
|
There's IMO a flaw in CxSkinButton::DrawItem method.
If the CxSkinButton object represents e.g. a checkbox with "normal" button text, the text in the pushed/checked state of the button is not displayed properly if the button becomes disabled. That is the position of the checked, disabled button text is wrong.
To fix this change the appropriate section in the DrawItem() method as follows:
// Select the correct skin
if (lpDrawItemStruct->itemState & ODS_DISABLED){ // DISABLED BUTTON
if(m_bDisabled.m_hObject==NULL)
// no skin selected for disabled state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else // paint the skin
DrawBitmap(pDC,(HBITMAP)m_bDisabled,r,m_DrawMode);
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
// paint the etched button text
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
//Fix: Check if button is in checked/pushed state
if (m_Checked)
OffsetRect(&tr,1,1);
pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
//Fix: Remove this line: OffsetRect(&tr,-1,-1);
pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
} else { // SELECTED (DOWN) BUTTON
...
|
|
|
|
|
Great class!
I'm working on a user-skinnable application so I need to load the images from files. The way I accomplished this was to replace the UINT's with LPCTSTR's in the SetSkin() parameters and modified the following code:
if (normal>0)
{
HBITMAP hNormal=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
normal,
IMAGE_BITMAP,
0,
0,
LR_LOADFROMFILE);
m_bNormal.Attach(hNormal);
}
My question is, will this cause any problems, or is there any additional clean-up that I need to be concerned with? I'm fairly new to C++.
Thanks,
Wolf
|
|
|
|
|
WolfSupernova wrote:
Great class!
thanks
WolfSupernova wrote:
will this cause any problems
you must release the bitmaps in the destructor or before you Attach a bitmap over an existing one. With resources this was not necessary
|
|
|
|
|
I want to have the same effect on key board usage.
What I mean is that when you push up-arrow key
the button change the state from normal to mouse over
Thanks
Shin
|
|
|
|
|
|
Hey.
I have a question.
In my program, i want to hide the buttons so they dont' show up in some pages, any of you know how to do that ?
thanks.
|
|
|
|
|
Hi again.
I just figured it out =)
groups.google.com is a good resource as well.
I used the ShowWindow function.
ShowWindow(SW_SHOW);
or
ShowWindow(SW_HIDE);
thanks anyways
|
|
|
|
|
Hey.
I have a question.
In my program, i want to hide the buttons so they dont' show up in some pages, any of you know how to do that ?
thanks.
|
|
|
|
|
I'm currently using the cxSkinButton class and noticed some problems with it under VC++7. It's not a huge deal but kind of annoying. If I create a new project using the wizard and include the manifest the tool tips don't work 100%. They will show up but if I click a button the tool tip for that button doesn't come back. Also, if I hold my mouse over a button until the tool tip goes away it won't come back again either. I'm only able to get the tool tip to come back if I pop up an AfxMessageBox and then close it. If I create another new project without a manifest the tool tips work perfectly. Has anybody else had this problem? I'm not even adding anything into the manifest. It only contains the stuff that VC++ puts in there by default. I could just remove the manifest but then I'd lose the newer interface features like the rounded buttons etc. I guess I could just use the skin control and make them whatever I want anyway but I'd like to find away to make the tool tips work right with the manifest and cxSkinButton.
-scully12
|
|
|
|
|
Hi scully12,
I have the same problem here with the lost tooltips, independent if I use the CxSkinButton class or simply the CButton class. So, CxSkinButton is not the reason why, it seems to be a general problem in VC++7 (the same sources built with VC++6 work perfectly, w/o the manifest, of course).
Did you find any solution in the meantime fro the issue?
Bernd
|
|
|
|
|
Hi Bernd,
I never did find a solution. I ended up just removing the manifest and using it that way. I was hoping that it really was a bug in VC and it would get fixed eventually. It's good to hear that I'm not crazy though.
-scully12
|
|
|
|
|
Hi scully12,
I have the same problem, I add some code at when the button losted focus.
//code :
if ( m_ctrlTooltip.m_hWnd != NULL )
m_ctrlTooltip.Pop();
//code end;
now, my button work fine!
sorry, my english was very pool
|
|
|
|
|
Thank you very much! This helped me fix a bug — tooltip didn't disappear when we moved the mouse pointer away from the button:
LRESULT CxSkinButton::OnMouseLeave(WPARAM, LPARAM)
{
if (m_tooltip.m_hWnd != NULL)
m_tooltip.Pop();
...
|
|
|
|
|
Hi!
I have a small improvement for the tooltip of a CxSkinButton. With this function you can colorize the tooltip as you want. The first COLORREF ist the text color, the second is the background color.
<br />
void CxSkinButton::SetToolTipColor(COLORREF crText, COLORREF crBkgnd)<br />
{<br />
if(m_tooltip.m_hWnd != NULL)<br />
{<br />
if(crText != NULL )<br />
m_tooltip.SetTipTextColor(crText);<br />
<br />
if(crBkgnd != NULL)<br />
m_tooltip.SetTipBkColor(crBkgnd);<br />
}<br />
}<br />
Perhaps someone will have use for it...
bye...
|
|
|
|
|
Thank you. Maybe it's time to update the article
|
|
|
|
|
Sorry, I made a small mistake in the 'SetToolTipColor' function.
If you check the COLORREF for not NULL you can't set the COLORREF to #000000 (black).
So the correct code is:
void CxSkinButton::SetToolTipColor(COLORREF crText, COLORREF crBkgnd)
{
if(m_tooltip.m_hWnd != NULL)
{
m_tooltip.SetTipTextColor(crText);
m_tooltip.SetTipBkColor(crBkgnd);
}
}
Here is another small function for the compensation of my bug
Call this function if you have enough of those colorized tooltips...
void CxSkinButton::ResetToolTipColor()
{
if(m_tooltip.m_hWnd != NULL)
{
m_tooltip.SetTipTextColor(GetSysColor(COLOR_INFOTEXT));
m_tooltip.SetTipBkColor(GetSysColor(COLOR_INFOBK));
}
} The function will set the tooltip text and background color to the system default.
|
|
|
|
|
Hi,
I've added a multiple line support for scinned buttons. The method CxSkinButton::DrawItem looks
now like follows:
void CxSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT (lpDrawItemStruct);
//TRACE("* Captured: %08X\n", ::GetCapture());
//Check if the button state in not in inconsistent mode...
POINT mouse_position;
if ((m_button_down) && (::GetCapture() == m_hWnd) && (::GetCursorPos(&mouse_position))){
if (::WindowFromPoint(mouse_position) == m_hWnd){
if ((GetState() & BST_PUSHED) != BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(TRUE);
return;
}
} else {
if ((GetState() & BST_PUSHED) == BST_PUSHED) {
//TRACE("* Inconsistency up detected! Fixing.\n");
SetState(FALSE);
return;
}
}
}
CString sCaption;
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC); // get device context
RECT r=lpDrawItemStruct->rcItem; // context rectangle
int cx = r.right - r.left ; // get width
int cy = r.bottom - r.top ; // get height
// get text box position
RECT tr={r.left+m_FocusRectMargin+2,r.top,r.right-m_FocusRectMargin-2,r.bottom};
//R.K. 07.03.03 New values for multi-line support
RECT rectsave = tr;
int hsize;
int iret;
GetWindowText(sCaption); // get button text
pDC->SetBkMode(TRANSPARENT);
// Select the correct skin
if (lpDrawItemStruct->itemState & ODS_DISABLED){ // DISABLED BUTTON
if(m_bDisabled.m_hObject==NULL)
// no skin selected for disabled state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else // paint the skin
DrawBitmap(pDC,(HBITMAP)m_bDisabled,r,m_DrawMode);
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
// paint the etched button text
pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
//RK pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
// R.K. 07.03.03 Calculate new values for multi-line support
hsize = tr.bottom - tr.top; // Check maxsize of Rect
// Calc hsize of multiline text
iret = pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CALCRECT|DT_CENTER);
tr = rectsave;
tr.top = (hsize - iret) / 2;
pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CENTER);
pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));
OffsetRect(&tr,-1,-1);
//RK pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
hsize = tr.bottom - tr.top;
iret = pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CALCRECT|DT_CENTER);
tr = rectsave;
tr.top = (hsize - iret) / 2;
pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CENTER);
} else {
// SELECTED (DOWN) BUTTON
if ((lpDrawItemStruct->itemState & ODS_SELECTED)){
if(m_bDown.m_hObject==NULL)
// no skin selected for selected state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else { // paint the skin
DrawBitmap(pDC,(HBITMAP)m_bDown,r,m_DrawMode);
}
OffsetRect(&tr,1,1); //shift text
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_SUNKEN,BF_RECT);
} else {
// DEFAULT BUTTON
if(m_bNormal.m_hObject==NULL)
// no skin selected for normal state -> standard button
pDC->FillSolidRect(&r,GetSysColor(COLOR_BTNFACE));
else // paint the skin
if ((m_tracking)&&(m_bOver.m_hObject!=NULL)){
DrawBitmap(pDC,(HBITMAP)m_bOver,r,m_DrawMode);
} else {
DrawBitmap(pDC,(HBITMAP)m_bNormal,r,m_DrawMode);
}
// if needed, draw the standard 3D rectangular border
if (m_Border) pDC->DrawEdge(&r,EDGE_RAISED,BF_RECT);
}
// paint the focus rect
if ((lpDrawItemStruct->itemState & ODS_FOCUS)&&(m_FocusRectMargin>0)){
r.left += m_FocusRectMargin ;
r.top += m_FocusRectMargin ;
r.right -= m_FocusRectMargin ;
r.bottom -= m_FocusRectMargin ;
DrawFocusRect (lpDrawItemStruct->hDC, &r) ;
}
// paint the enabled button text
pDC->SetTextColor(m_TextColor);
//RK pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
int hsize = tr.bottom - tr.top;
int iret = pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CALCRECT|DT_CENTER);
tr = rectsave;
tr.top = (hsize - iret) / 2;
pDC->DrawText(sCaption,&tr, DT_WORDBREAK|DT_CENTER);
}
}
Hope this is helpful.
Robert
|
|
|
|
|
Hi,
I tried your version of multiline, but in the demo-version, it shows de radiobuttons and checkboxes aren't properly displayed anymore. What I mean is that they seem to "forget" there checked status.
For normal pushbuttons, it works, but only when checking the "multiline"-option in the resource-properties of the multiline-button.
Have you noticed this problem also? Any idea how to solve it?
Greetz,
Peggy
|
|
|
|
|
I have a set of buttons on my dialog. I've implemented a resize button class that inherits from CxResizeButton and uses SetWindowPos to set the dialog's size.
The dialog also has a layout manager I wrote that monitors onSize and repositions the buttons and other controls.
If I don't enable WS_CLIPCHILDREN I get lots of flickering, which is logical since the entire background is redraw and so are the masked buttons I have on it. If I enable this style, There is no flickering during resizing, but for some reason the buttons don't display correctly. From what I've managed to figure, the mask is scaled 1 extra pixel to the left of the button, creating a vertical line that has a buggy display instead of displaying the background image.
any idea why this happens ?
thanks for your time guys
|
|
|
|
|
I try to show a popup menu besiding the button through RButtonDown message.
1. Add OnRButtonDown() function.
2. Use TrackPopupMenu() to popup menu besiding the button.
3. Menu appears.
4. Selects a item of menu or clicks any point on screen out of the
region of button to make the menu disapper.
5. An error occured.
77F767CD int 3
Could anyone kindly give me some advice?
Best regards!
|
|
|
|
|
Hi,
thanks for very good works.
BoundsCheck report that an error at the
SelectClipRgn((HDC)GetDC(), hClipRgn);
which the HDC is not valid.
I change the (HDC)GetDC() to GetDC()->m_hDC
this time the SelectClipRgn just return an
ERROR if you change it to:
if(SelectClipRgn(GetDC()->m_hDC, hClipRgn)==ERROR)
AfxMessageBox("ERROR");
it seems that some thing is wrong with the
hClipRgn.
Anyone can help me?
Thanks
|
|
|
|
|