Click to See Complete Forum and Search --> : Layered Window -- Strange behavior


TheDominis
June 26th, 2010, 10:22 AM
I'm trying to get a layered window to drag with the mouse, but it isn't even possible to click the window without it exhibiting behavior as if it were created with WS_EX_TRANSPARENT.


#include <iostream>

#include <windows.h>

static const int kWindowHeight = 256;
static const int kWindowWidth = 256;

bool PaintWindow(HWND hwnd) {
HDC wdc = GetDC(hwnd);
if(!wdc) {
std::cout << std::endl << "error. getting dc";
}
HDC mdc = CreateCompatibleDC(wdc);
if(!mdc) {
std::cout << "error. creating dc";
}
HBITMAP mbm = CreateCompatibleBitmap(wdc, kWindowWidth, kWindowHeight);
if(!mbm) {
std::cout << std::endl << "error. creating bitmap";
}
HPEN pen = CreatePen(PS_SOLID, 12, RGB(255, 255, 255));
if(!pen) {
std::cout << std::endl << "error. creating pen";
}
if(!SelectObject(mdc, pen)) {
std::cout << std::endl << "error. select pen";
}
if(!SelectObject(mdc, mbm)) {
std::cout << std::endl << "error. select bitmap";
}
if(!MoveToEx(mdc, 0, 0, NULL)) {
std::cout << std::endl << "error. move to";
}
if(!LineTo(mdc, kWindowWidth, kWindowHeight)) {
std::cout << std::endl << "error. line to";
}
SIZE size;
size.cx = kWindowWidth;
size.cy = kWindowHeight;
POINT point;
point.x = 0;
point.y = 0;
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.AlphaFormat = AC_SRC_ALPHA;
blend.SourceConstantAlpha = 255;
if(!UpdateLayeredWindow(hwnd, wdc, &point, &size, mdc, &point, 0, &blend, ULW_ALPHA)) {
std::cout << std::endl << "error. update layered window";
}
if(!DeleteDC(mdc)) {
std::cout << std::endl << "error. delete dc";
}
if(!DeleteObject(mbm)) {
std::cout << std::endl << "error. delete bitmap";
}
if(!DeleteObject(pen)) {
std::cout << std::endl << "error. delete pen";
}
if(!ReleaseDC(hwnd, wdc)) {
std::cout << std::endl << "error. release dc";
}
return true;
}

LRESULT WINAPI WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_MOUSEMOVE:
{
POINTS point = MAKEPOINTS(lParam);
std::cout << std::endl << "(" << point.x << ", " << point.y << ")";
return 0;
}
// case WM_NCHITTEST: // for dragging
// return 2;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_QUIT:
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}

int main(int argc, char* argv[]) {
WNDCLASSEX wnd;
ZeroMemory(&wnd, sizeof(wnd));
wnd.cbSize = sizeof(wnd);
wnd.lpfnWndProc = WindowProc;
wnd.hbrBackground = CreateSolidBrush(RGB(0, 255, 0));
wnd.lpszClassName = L"MagicBlend";
std::cout << "magic!";
if(!RegisterClassEx(&wnd)) {
std::cout << std::endl << "error. registering class";
std::cin.get();
return -1;
}
HWND hwnd = CreateWindowEx(WS_EX_LAYERED, wnd.lpszClassName, NULL, WS_OVERLAPPEDWINDOW, 0, 0, kWindowWidth, kWindowHeight, NULL, NULL, wnd.hInstance, NULL);
if(!hwnd) {
std::cout << std::endl << "error. creating window";
std::cin.get();
return -2;
}
MSG msg;
ShowWindow(hwnd, SW_SHOW);
PaintWindow(hwnd);
while(GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}


Any help would be appreciated.

ovidiucucu
June 27th, 2010, 06:29 AM
One first help.
Always paint a window when handle WM_PAINT message (http://msdn.microsoft.com/en-us/library/dd145213(VS.85).aspx).

TheDominis
June 28th, 2010, 06:55 PM
One first help.
Always paint a window when handle WM_PAINT message (http://msdn.microsoft.com/en-us/library/dd145213(VS.85).aspx).

It may be recommended to paint in response to WM_PAINT messages and the like, but I've found that advising a person to always follows a certain paradigm is ostentatious.

The problem is that the bitmap was not 32 bits per pixel. Therefore, no alpha value was associated with the colors allowing the user to click through the window. Using CreateBitmap solved the issue.

Apparently GDI doesn't support drawing alpha values (from what I can tell). I'm using GDI+ now.

hoxsiew
June 29th, 2010, 08:11 AM
What makes you think GDI doesn't support alpha bitmaps?

ovidiucucu
June 30th, 2010, 04:42 AM
Apparently GDI doesn't support alpha values.
Just apparently.
On a deeper look in MSDN, it does.
See AlphaBlend Function (http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx).

TheDominis
July 3rd, 2010, 12:55 AM
Just apparently.
On a deeper look in MSDN, it does.
See AlphaBlend Function (http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx).

Can't draw with colors that have alpha.

Functions such as MoveToEx and LineTo.

hoxsiew
July 5th, 2010, 09:13 AM
Good point. GDI+ would be necessary for that. I still shy away from GDI+ because it is so gawd-awful slow compared to GDI. For something like you describe, I'd probably compose the lines, etc. as a bitmap in photoshop or gimp and then use AlphaBlend in GDI.