 |
|
|
 |
|
|
 |
|
 |
I have a WinCE application that has one bitmap set as the background for the dialog and a smaller bitmap set as the background for an inner window. I tried using setbkgnd(transparent) but it seems to be taking the lower bitmap as background (dark grey.. almost black) while the background I want is the one that is directly below the text box (off white)
|
|
|
|
 |
|
 |
Hello sir,
Can we change the background colour of static control without using code. By default, the background colour of static control is in a brown colour. Can we change it into any other colour.
Regards
Ansif
|
|
|
|
 |
|
 |
you article does the job, but the article a bit too much succint.
you could for instance show a piece of the code of the function you describe, instead of only explain what it does.
something like this would have fitted me :
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
<font color=blue>if</font> (nCtlColor == CTLCOLOR_STATIC) {
<font color=blue>if</font> (pWnd->GetDlgCtrlID() == m_staticTransparent.GetDlgCtrlID()) {
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(192, 192, 192));
hbr = <font color=blue>static_cast</font><HBRUSH>(GetStockObject(NULL_BRUSH));
}
}
<font color=blue>return</font> hbr;
}
for what i saw you suggesting to some other guys, Invalidate()-ing a control enforces it to be redrawn entierely ; no need then to hide and to unhide it...
-- modified at 18:01 Tuesday 9th January, 2007
-- modified at 18:03 Tuesday 9th January, 2007
|
|
|
|
 |
|
 |
I think that for this example to be correct you need to
if (hbr) ::DeleteObject(hbr)
before changing it to NULL_BRUSH. Otherwise there will be resource leak and strange visual artifacts sometimes.
|
|
|
|
 |
|
 |
SetWindowText leaves the old text on the screen and draws the new text on top of it.
|
|
|
|
 |
|
 |
When you do this, the old text doesn't get erased because of the Nuill Brush being used for the background. The new text just gets or'd over it and you end up with garbage.
The workaround I am using in my application is to Hide the static item, change the text and then Show the item.
|
|
|
|
 |
|
 |
no need to hide... simply Invalidate() the control
|
|
|
|
 |
|
 |
Comment out SetBkMode(TRANSPARENT) and see what happened
|
|
|
|
 |
|
 |
Then the control is not longer transparent!?
|
|
|
|
 |
|
 |
I don't think your method is enough for CTreeCtrl
does anyone know how to paint Tree Control transparently,
like CATIA's GUI.
Best Regards
|
|
|
|
 |
|
 |
I have noticed that if you entered the text in the resource editor or in OnInitDialog() it works BUT if you try this somewhere else the control is not transparent anymore :
Assuming you have assigned a control variable m_staText :
BOOL CTestDlg::OnInitDialog()
{
m_staText.SetWindowText("Transparent"); WORKS
}
void CTestDlg::OnBnClickedBtn()
{
m_staText.SetWindowText("Transparent"); FAILED
}
|
|
|
|
 |
|
 |
When you do this, the old text doesn't get erased because of the Nuill Brush being used for the background. The new text just gets or'd over it and you end up with garbage.
The workaround I am using in my application is to Hide the static item, change the text and then Show the item.
|
|
|
|
 |
|
 |
for c# anybody has sample code?
|
|
|
|
 |
|
 |
Derive the label class and set the control style to add ControlStyles.SupportsTransparentBackColor. You can simply set the BackgroundImage property in the forms designer to set the background bitmap.
|
|
|
|
 |
|
 |
You can simply set the BackgroundImage property in the forms designer to set the background bitmap. Set the BackColor of the label to Transparent. If you need to do blending, you can derive the label class and set the control style to add ControlStyles.SupportsTransparentBackColor and then set the alpha component appropriately of the back color.
|
|
|
|
 |
|
 |
Thanks danamac. It was great to find a new tool for non-standard Windows GUI development. I am currently changing the face of a monolithic app with 50 dialogs some of which are used as templates for literally hundreds of custom dialogs. While I have a solution which works (as the backgrounds will remain plain colors as opposed to textures or bitmaps) by setting the control brush to the intended color I would like to see if I can use the transparency method you have here. Unfortunately the check boxes are being interpreted as static text by OnCtlColor and with the NULL_BRUSH being returned are black boxes with only the check box visible. Do you have any suggestions for making the text of the check box transparent or filtering them out from the static text controls in OnCtlColor? I am looking for solutions I can put into an inserted base class between CDialog and the apps dialog classes.
Thanks,
StickJock
|
|
|
|
 |
|
 |
Now that you point it out, I see that checkboxes do indeed come in with nCtlColor == CTLCOLOR_STATIC and therefore get drawn with the TRANSPARENT background mode and NULL_BRUSH.
However, I have checkboxes (and radio buttons) in my application, using this technique, and they appear fine (no black boxes). I added a checkbox to the sample code and that also seems fine.
What I have noticed is if I change the text of a static item while it is currently being displayed, the original text doesn't get erased, the new text is just drawn transparently over the old text which results in garbage.
I found a workaround for this is to hide the item, change the text, then show the item.
I don't know if this relates to what you are experiencing.
|
|
|
|
 |
|
 |
To fix this problem, just add this to your OnCtlColor method :
if (nCtlColor == CTLCOLOR_STATIC)
{
int nId = pWnd->GetDlgCtrlID();
if (nId == IDC_CHECK_PROBLEM)
{
CRect rc;
pWnd->GetClientRect(rc);
pDC->BitBlt(0, 0, rc.right - rc.left, rc.bottom - rc.top,
pWnd->GetDC(), rc.left, rc.top, SRCCOPY);
}
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
}
|
|
|
|
 |
|
 |
Many thanks! It's the correct solution.
|
|
|
|
 |
|
 |
Doesn't work for checkboxes and comboboxes when XP Style is used in application.
C++ libraries at a give-away price on www.neatcpp.com: TWAIN, DirectShow, Interprocess Communications, etc...
|
|
|
|
 |
|
 |
Perhaps you're using CommonControls < 6.0.
If set it to 6.0 this behavior is 100% reproducible.
And because there's no workaround, this article seems to be incomplete.
|
|
|
|
 |
|
 |
draw the parent's background in the WM_ERASEBKGND of the control... Then you don't have to worry about anything undocumented.
Sub- or superclass the static control and fetch WM_ERASEBACKGROUND. I have an own STATIC, so that's not what I tested though - if STATIC paints its background in WM_PAINT, you're lost again.
The only requirement for the code is that the parent draws its background in WM_ERASEBKGND (which it should).
Christian
RECT rcClientThis;
HWND hWndParent = GetParent(hWnd);
RECT rcClientParent;
POINT ptOrg;
if (pRC != NULL)
rcClientThis = *pRC;
else
{
GetWindowRect(hWnd,&rcClientThis);
ScreenToClient(hWndParent,(POINT*)&rcClientThis.left);
ScreenToClient(hWndParent,(POINT*)&rcClientThis.right);
}
GetWindowRect(hWndParent,&rcClientParent);
OffsetWindowOrgEx(hDC,rcClientThis.left-rcClientParent.left,rcClientThis.top-rcClientParent.top,&ptOrg);
SendMessage(hWndParent,WM_ERASEBKGND,(WPARAM)hDC,0);
SetWindowOrgEx(hDC,ptOrg.x,ptOrg.y,NULL);
|
|
|
|
 |
|
 |
I did it by this way. You can reuse it: //NEEDED - Whole file #if !defined(AFX_TRANSPARENTSTATIC_H__EF437069_0E0C_4816_B8AC_E40D2AD0C02D__INCLUDED_) #define AFX_TRANSPARENTSTATIC_H__EF437069_0E0C_4816_B8AC_E40D2AD0C02D__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // TransparentStatic.h : header file // ///////////////////////////////////////////////////////////////////////////// // CTransparentStatic window class CTransparentStatic : public CStatic { // Construction public: static CBrush m_brushTransparent; CTransparentStatic(); void SetWindowText(LPCTSTR lpszString); // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CTransparentStatic) //}}AFX_VIRTUAL // Implementation public: virtual ~CTransparentStatic(); // Generated message map functions protected: //{{AFX_MSG(CTransparentStatic) afx_msg BOOL OnEraseBkgnd(CDC* pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_TRANSPARENTSTATIC_H__EF437069_0E0C_4816_B8AC_E40D2AD0C02D__INCLUDED_)
//NEEDED - Whole file // TransparentStatic.cpp : implementation file // #include "stdafx.h" #include "vs6transparentstatic.h" #include "TransparentStatic.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTransparentStatic CBrush CTransparentStatic::m_brushTransparent; CTransparentStatic::CTransparentStatic() { if (m_brushTransparent.GetSafeHandle()) return; m_brushTransparent.CreateStockObject(NULL_BRUSH); } CTransparentStatic::~CTransparentStatic() { }
BEGIN_MESSAGE_MAP(CTransparentStatic, CStatic) //{{AFX_MSG_MAP(CTransparentStatic) ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CTransparentStatic message handlers
void CTransparentStatic::SetWindowText(LPCTSTR lpszString) { CWnd *pParent = GetParent(); if (pParent) { CRect rcStatic; GetWindowRect(rcStatic); pParent->ScreenToClient(rcStatic); pParent->InvalidateRect(rcStatic); pParent->SendMessage(WM_PAINT); } CStatic::SetWindowText(lpszString); }
BOOL CTransparentStatic::OnEraseBkgnd(CDC* pDC) { return TRUE; }
// VS6TransparentStaticDlg.h : header file // #if !defined(AFX_VS6TRANSPARENTSTATICDLG_H__F0DDB6B4_6447_4FD0_BE53_93214E7672D5__INCLUDED_) #define AFX_VS6TRANSPARENTSTATICDLG_H__F0DDB6B4_6447_4FD0_BE53_93214E7672D5__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#include "TransparentStatic.h"
///////////////////////////////////////////////////////////////////////////// // CVS6TransparentStaticDlg dialog class CVS6TransparentStaticDlg : public CDialog { // Construction public: CVS6TransparentStaticDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CVS6TransparentStaticDlg) enum { IDD = IDD_VS6TRANSPARENTSTATIC_DIALOG }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CVS6TransparentStaticDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; //NEEDED CTransparentStatic m_oTS; // Generated message map functions //{{AFX_MSG(CVS6TransparentStaticDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); //NEEDED afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnDestroy(); afx_msg BOOL OnEraseBkgnd(CDC *pDC); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_VS6TRANSPARENTSTATICDLG_H__F0DDB6B4_6447_4FD0_BE53_93214E7672D5__INCLUDED_)
// VS6TransparentStaticDlg.cpp : implementation file // #include "stdafx.h" #include "VS6TransparentStatic.h" #include "VS6TransparentStaticDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CVS6TransparentStaticDlg dialog CVS6TransparentStaticDlg::CVS6TransparentStaticDlg(CWnd* pParent /*=NULL*/) : CDialog(CVS6TransparentStaticDlg::IDD, pParent) { //{{AFX_DATA_INIT(CVS6TransparentStaticDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CVS6TransparentStaticDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CVS6TransparentStaticDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CVS6TransparentStaticDlg, CDialog) //{{AFX_MSG_MAP(CVS6TransparentStaticDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() //NEEDED ON_WM_CTLCOLOR() ON_WM_TIMER() ON_WM_DESTROY() ON_WM_ERASEBKGND() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CVS6TransparentStaticDlg message handlers BOOL CVS6TransparentStaticDlg::OnInitDialog() { CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon //NEEDED CWnd *pStatic = GetDlgItem(IDC_S); if (pStatic) m_oTS.SubclassWindow(pStatic->GetSafeHwnd()); SetTimer(1, 50, NULL); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CVS6TransparentStaticDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CVS6TransparentStaticDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } HBRUSH CVS6TransparentStaticDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { //NEEDED if (nCtlColor == CTLCOLOR_STATIC) { pDC->SetBkMode(TRANSPARENT); return CTransparentStatic::m_brushTransparent; } return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); } void CVS6TransparentStaticDlg::OnTimer(UINT nIDEvent) { static int i = 0; CString str; str.Format(_T("%d"), i++); //NEEDED - Invokation of overriden CTransparentStatic::SetWindowText() CTransparentStatic *pS = (CTransparentStatic *)GetDlgItem(IDC_S); pS->SetWindowText(str); CDialog::OnTimer(nIDEvent); } void CVS6TransparentStaticDlg::OnDestroy() { CDialog::OnDestroy(); KillTimer(1); }
BOOL CVS6TransparentStaticDlg::OnEraseBkgnd(CDC *pDC) { CRect rc; GetClientRect(rc); CBrush brush; brush.CreateHatchBrush(HS_DIAGCROSS, 0); pDC->FillRect(rc, &brush); return TRUE; }
B.
|
|
|
|
 |