Click here to Skip to main content
15,892,059 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am trying to create a transparent window using Win32 API which can be dragged across the screen and the window's background will keep on being transparent and showing the windows behind it.

I'm doing so by performing the following:
C++
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= NULL;
	wcex.hbrBackground	= NULL;
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= NULL;

	return RegisterClassEx(&wcex);
}


The:
wcex.hbrBackground = NULL;
line is responsible of making the window transparent upon initialization.

Creating the window is done in:
C++
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}


And the way the window keeps on being transparent upon dragging is:
C++
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_MOVING:
		InvalidateRect(hWnd, NULL, TRUE); 
		break;
	default:
		return = DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}


Where the:
InvalidateRect(hWnd, NULL, TRUE);
line causes the window to be redrawn upon moving event.

The problem is that the background of the window is not re-rendered in the regions which are not "new".
For example,
say I open an application (word, chrome etc. - lets call it WindowB) and than I run my application which opens WindowA that covers WindowB but I can see the content of WindowB in the background (since WindowA is a transparent window). If I drag WindowA across the screen I still see WindowB in the background and that's great.
If I minimize WindowB I still see portion of WindowB which intersects WindowA region (No problem here since I didn't redraw WindowA).
If I start to drag WindowA, I assumed that WindowB portion showed in WindowA will disappear and I'll see what's currently is the top most window in the desktop as WindowA's background, since I call InvalidateRect(hWnd, NULL, TRUE); upon the moving event.
What actually happens is that I still see WindowB in all the regions which are not "new regions" - by new regions I mean regions in the screen where WindowA was moved to and was not part of WindowA region before the move.
It seems that the call for InvalidateRect(hWnd, NULL, TRUE); is not enough since it renders only "new regions".

I would very much appreciate any assistance on this issue.

The main function of my application is the default function created by Visual Studio 2010 for a Win32 Application project:
C++
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_TEST2, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST2));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}


Thanks,
Gidi
Posted
Comments
nv3 19-Aug-14 16:59pm    
Could be a side effect of the CS_SAVEBITS window class style. Have you experimented with that already?
Member 11021885 20-Aug-14 2:06am    
No I haven't, could you please elaborate?
Thanks.
nv3 20-Aug-14 4:30am    
Take a look at Window Class Styles

Telling from your code you have CS_SAVEBITS not set, which should be okay.
[no name] 22-Aug-14 12:50pm    
What you're doing isn't transparency. All you are really doing is failing to paint the background. Consider a different approach.

UPDATELAYEREDWINDOWINFO structure

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900