Solved

Win32 non MFC solution to have STATIC TEXT items with TRANSPARENT background

Posted on 2004-08-12
14
4,858 Views
Last Modified: 2013-12-03
I would like to have a solution for the problem that's not written with MFC code or similiar, but uses "lo-level" Win32 apis C calls.

// create a window class with
aWc.hbrBackground      = (HBRUSH) COLOR_BACKGROUND;
      
// create a window "on aWc" window class
hWnd = CreateWindow(WS_OVERLAPPEDWINDOW,...)

// add a text
hControl = CreateWindowEx(0,"STATIC",  "Wanna be transparent", WS_VISIBLE | WS_CHILD , ....);

ShowWindow(hControl, SW_SHOW );
ShowWindow(hWnd, SW_SHOW );

[...messages loop code... ]

The result can be that the background color of the hControl is not the one specified in aWc.hbrBackground.
Also, I would like a solution that declares really the control transparent so that every control, for every color or brush
specified in aWc.hbrBackground (for instance (HBRUSH)GetStockObject(RED_BRUSH);) is drown "correctly".

I would like also that the solution works if I organize trees of child windows like...
hWnd1
  hWnd2
    hControl1
    hControl2
  hWnd3
    hControl3
  hWnd4
    hWnd5
     hControl4
     hControl5

...or if the text is put over an image control, or over other rectangular child windows which have a different background colors. So the text should be really transparent.

Thanks.
0
Comment
Question by:luciocosmo
  • 7
  • 6
14 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11790485
I think you have to create your controls with the WS_EX_TRANSPARENT  attribute in the first argument of CreateWindowEx().

0
 

Author Comment

by:luciocosmo
ID: 11791380
Sorry, too easy. It does not work.
Here is the complete code.
with USE_USE_BRUSH_INDEX to 0, the problem does not appear on XP with CLASSIC window desktop theme; if set to 1, it does with XP and CLASSIC themes. The problem comes out also with "BUTTON" class and BS_RADIOBUTTON or BS_CHECKBOX.
Here follows the complete code I'm doing the tests with. Note that I'm setting the background colour in the window class declaration: is this the wrong place ?

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

// ----------------------------------------------------------------------------------------------

LRESULT CALLBACK WndProc( HWND hWnd, UINT messg,WPARAM wParam, LPARAM lParam );
HMENU GetAMenuBar(void);
void CreateMyWindow(HINSTANCE hInst);

// ----------------------------------------------------------------------------------------------

char szProgName[200] = { "Hello A" };

HMENU GetAMenuBar(void)
{
    HMENU        hFileMenu;            
    HMENU        hMenu;                
    MENUITEMINFO item;                  

    hMenu     = CreateMenu();
    hFileMenu = CreateMenu();

    item.cbSize      = sizeof(MENUITEMINFO);
    item.fMask       = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
    item.fType       = MFT_STRING;
    item.hSubMenu    = NULL;

    item.wID        = 'x';
    item.dwTypeData = "E&xit";
    item.cch        = strlen("E&xit");
    InsertMenuItem(hFileMenu, 0, FALSE, &item);
   
    item.wID        = 0;
    item.dwTypeData = "&File";
    item.cch        = strlen("&File");
    item.hSubMenu   = hFileMenu;
    InsertMenuItem(hMenu, 0, FALSE, &item);
   
    return hMenu;
}

// ----------------------------------------------------------------------------------------------

#define USE_BRUSH_INDEX 0

void CreateMyWindow(HINSTANCE hInst)
{
      WNDCLASS wc;
      HMENU hMenu;
    RECT vRect;
    HWND hWnd;
    HWND hControl;
      
    hMenu = GetAMenuBar();
   
      wc.lpszClassName       = szProgName;
      wc.hInstance             = hInst;
      wc.lpfnWndProc            = WndProc;
      wc.hCursor                  = LoadCursor( NULL, IDC_ARROW );
      wc.hIcon                  = LoadIcon( NULL, IDI_APPLICATION );
      wc.lpszMenuName            = 0;
      wc.style                  = 0;
      wc.cbClsExtra            = 0;
      wc.cbWndExtra            = 0;
   
    if (USE_BRUSH_INDEX == 1)
          wc.hbrBackground      = (HBRUSH) GetStockObject( WHITE_BRUSH );
      else
          wc.hbrBackground      = (HBRUSH) COLOR_BACKGROUND;
      
      RegisterClass( &wc );
      
      vRect.left = 100;
      vRect.top = 100;
      vRect.right = 100+400;
      vRect.bottom = 100+200;
      
      AdjustWindowRect(&vRect,WS_OVERLAPPEDWINDOW,TRUE);
      
    hWnd = CreateWindowEx(       
          WS_EX_CLIENTEDGE,
          szProgName,                                    
          szProgName,
          WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT,
          CW_USEDEFAULT,
          vRect.right-vRect.left,
          vRect.bottom-vRect.top,
          (HWND)NULL,
          hMenu,
          (HANDLE)hInst,
          (LPSTR)NULL            );
   
    hControl = CreateWindowEx(
       WS_EX_TRANSPARENT,
       "STATIC",
       "I wanna be transparent",
       WS_VISIBLE | WS_CHILD,
       10,
       100,
       200,
       25,
       hWnd,
       (HMENU) 10,
       (HANDLE)hInst,
       (LPSTR) NULL);
   
      ShowWindow(hControl, SW_SHOW );
      ShowWindow(hWnd, SW_SHOW );
      UpdateWindow( hWnd );

}

// ----------------------------------------------------------------------------------------------
                  
int WINAPI WinMain( HINSTANCE hInst,       
                              HINSTANCE hPreInst,
                              LPSTR lpszCmdLine,
                              int nCmdShow )
{

      MSG lpMsg;
      
      (hPreInst);
      (lpszCmdLine);
      (nCmdShow);
      
    CreateMyWindow(hInst);
   
      while( GetMessage( &lpMsg, NULL, 0, 0 ) )                        
      {
            TranslateMessage( &lpMsg );
            DispatchMessage( &lpMsg );
      }
      
      return( lpMsg.wParam);
}

// ----------------------------------------------------------------------------------------------


LRESULT CALLBACK WndProc( HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam )
{
      HDC hdc;                         
      PAINTSTRUCT pstruct;
      
      switch(messg)
      {
          case WM_PAINT:
                hdc = BeginPaint(hWnd, &pstruct );             
                EndPaint(hWnd, &pstruct );      
                break;
            
            case WM_DESTROY:
                PostQuitMessage( 0 );
                break;
          
          case WM_CLOSE:
              DestroyWindow(hWnd);
              return 0;
              
            default:
                return( DefWindowProc( hWnd, messg, wParam, lParam ) );
      }

      return( 0L );
}

0
 

Author Comment

by:luciocosmo
ID: 11850261
Hey, no one has ideas ?
0
 

Author Comment

by:luciocosmo
ID: 11900689
Still no replies, increased value again !
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 11960408
luciocosmo,
Be patient... This Q will be featured in the upcoming EE newsletter and that should stir up some interest :)
-- DanRollins / EE Page Editor
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11962670
You mentioned you want transparent controls but it appear to be that you want a whole transparent window, please be more specific.
0
 

Author Comment

by:luciocosmo
ID: 11962928
I'm interested to have transparent controls, in this question.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11963555
OK, Add this message handler:
             case WM_CTLCOLORSTATIC:
                  SetBkMode((HDC)wParam, TRANSPARENT);
                  return (LONG)(HBRUSH)(GetStockObject(NULL_BRUSH));

I have tested it, if you don't have expected result, advice me.
0
 

Author Comment

by:luciocosmo
ID: 11966440
Yes it works. I did do some tests with TRANSPARENT.
But what I did not explicitly write is that "an item is an item" and during execution I can change its values.

SetWindowText(hControl,"Change me please");

Does write the new text string over the other. I expect the system redraws the whole area correctly.
I expect also that other more complicated control hierarchies works, but this should be almost done when this simple code gets running :)

Thanks in advance.

0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 11969223
Does write the new text string over the other. I expect the system redraws the whole area correctly.
I guess you have to control the WM_ERASEBKGND event and erase by yourself.
0
 

Author Comment

by:luciocosmo
ID: 11990688
It's not generic. Consider a more complicate situation, where there are several controls on the window. I need to issue the simpliest command to change a control text.
Do you mean that I should set the text, erase the control area background and then invalidate that area ?

Please be clearer.

 
0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 500 total points
ID: 11991717
You have 2 alternatives: paint the background at the control's painting event or send an invalidate message to the windows to force it to repaint the area you will.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12002167
Also you can order the entire container window to repaint, this will repaint the background and all the controls.
0
 

Author Comment

by:luciocosmo
ID: 12003770
I will try this in a more complex situation. I need to check with some code. Will be back in 1-2 days
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article describes a technique for converting RTF (Rich Text Format) data to HTML and provides C++ source that does it all in just a few lines of code. Although RTF is coming to be considered a "legacy" format, it is still in common use... po…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now