Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 2004-08-12
14
4,873 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

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
 
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

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
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…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

838 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