How to prevent underlay child window from receving messages (windows API) - windows

now I have 2 child windows overlapping on each others.
first one is a button. (Created First)
second one is just a black Rectangle created after the button and the list box under it(in the Linked image)
when the black child Created it's been painted and get the button covered correctly . and also when I hover the mouse over the area of the black child window it receives messages, but when the mouse enters the -hidden- underlay Button area , the button is repainting and clipping it's area from the overlapped black rect child window ,meaning it receives messages.
How can I prevent this button from receiving any messages when it's sibling -black child- is over?
Thanks in advance
the creating code of the black child
CreateWindowEx(0,controlerclassname,"",WS_CHILD|WS_VISIBLE,5,5,300,300,Hmainwin,0,Hinstance,0);
the WM_PAINT processing
HDC hdc;
PAINTSTRUCT ps;
RECT rc;
HBRUSH Hbrush;
GetClientRect(hwnd,&rc);
hdc = BeginPaint(hwnd,&ps);
Hbrush =CreateSolidBrush(RGB(10,10,10)); //(HBRUSH)GetStockObject(NULL_BRUSH); //
SelectObject(hdc,Hbrush);
Rectangle(hdc,rc.left,rc.top,rc.right,rc.bottom);
EndPaint(hwnd,&ps);
The Button Creating line
CreateWindowExA(0,"BUTTON" ,"Creat New Top Level Window", WS_CHILD | WS_VISIBLE | BS_FLAT, // Button Create
mainwndrc.left+10, mainwndrc.top+10 ,200,30,hwnd,(HMENU)ID_BTN_NEW,Hinstance,0);

Related

Why does repeating call to createBitmapIndirect in WM_MOUSEMOVE eventually returns NULL?

I'm writing a complex color editing dialog box which contains a list view control and a photoshop-style HSV color picker. This dialog will be used as described:
the user first clicks on the particular item, then manipulates cursor on the colorpicker to setup the right color for the item, then clicks another item and repeats the process.
My hotoshop stle HSV colorpicker is devided in two rectangels -
1. 256x20 color ramp that represents with full 360 span of HUEs
256x256 window that showes all the VALUES and SATURATION variation of the current selected HUE.
Realization:
I've made some research and decided to use GDI bitmaps.
So I fill in GDI BITMAP struct, get dc, get comaptable dc, and create hBitmap by CreateBitmapIndirect:
case WM_INITDIALOG:
bitmap_hsv.bmBits=&bits_hsv;
bitmap_hsv.bmBitsPixel=32;
bitmap_hsv.bmHeight=256;
bitmap_hsv.bmPlanes=1;
bitmap_hsv.bmType=0;
bitmap_hsv.bmWidth=256;
bitmap_hsv.bmWidthBytes=256*4;
hDC=GetDC(hDlg);
hDC_compat=CreateCompatibleDC(hDC);
hBitmap_hsv=CreateBitmapIndirect(&bitmap_hsv);
return (INT_PTR)TRUE;
Then on the mouse move I have to check if the user selected some other HUE in the hue ramp and if he did then I need to fill the byte array of my BITMAP by new values. In the listing for simplicity reasons every mouse move need change of HUE and refill the whole bitmap each call.
case WM_MOUSEMOVE:
if (wParam&MK_LBUTTON)
{
hDC=GetDC(hDlg);
pt.x=(LONG) LOWORD(lParam);//client coords
pt.y=(LONG) HIWORD(lParam);//client coords
H+=1;
if (H==360) H=0;
fill_bits_hsv(H,bits_hsv,4);
hBitmap_hsv=CreateBitmapIndirect(&bitmap_hsv);
if (!hBitmap_hsv)
{
err=GetLastError();
return 0;//I STOP CODE HERE TO SEE err=0;
}
SelectObject(hDC_compat,hBitmap_hsv);
BitBlt(hDC,0,0,255,255,hDC_compat,10,10,SRCCOPY);
drawCursor(pt.x,pt.y,hDC);
ReleaseDC(hDlg,hDC);
}
return 0;
It works ok for 40 or 50 first calls, but then all the window lags and looses DC, I can move the window, but the area is not refreshing. My stop mark shows the problem with
hBitmap=CreateBitmapIndirect(...) which shows 0x00000000 and GetLastError shows 0;
And now the main question what am I doing wrong?

display obscured control on bitmap

I have the HDC=hdc of a bit map, a rectangle R with logical coordinates in hdc, and the HWND=hwnd of a scroll control created by CreateWindow with SBS_HORZ. The scroll control is is the child of another window. I want to display the scroll control on the bitmap in rectangle R.
I obtained a HDC for the scroll control and used BitBlt to copy the control to the rectangle. All works well if the entire scroll control is visible in it's parent BUT if the scroll bar is obscured, I get what ever is on top of the bar. If the control is off the screen I get nothing.
This is all part of an effort to periodically save a screen image of the app in case you are wondering how the scroll bar can be obscured. I do not want to bring the scroll bar's parent to the front.
Is there anyway I can get a true image of the scroll bar in these conditions?
Or alternatively, could I somehow make a scroll bar that wasn't displayed who's contents I could copy? I do know all the parameters needed.
I found the following seems to work even if the control is obscured or off the screen. Create a DC and compatible bitmap from the control. Send the control a WM_PRINT message asking it to print itself in the DC/Bitmap. Then copy the bitmap using BitBlt.
Pretty ugly! Is there a better way?
Something like this...
HDC hdcScroll;
WINDOWPLACEMENT WP;
HDC memdc;
HBITMAP membit;
hdcScroll = GetDC (hwndScroll);
GetWindowPlacement (hwndScroll, &WP);
int Height = WP.rcNormalPosition.bottom - WP.rcNormalPosition.top;
int Width = WP.rcNormalPosition.right - WP.rcNormalPosition.left;
memdc = CreateCompatibleDC(hdcScroll); // destination DC
membit = CreateCompatibleBitmap(hdcScroll, Width, Height); // destination bitmap
HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit); // add bitmap to DC
SendMessage (hwndScroll,WM_PRINT,(WPARAM) memdc, PRF_CLIENT);
BitBlt
(hdc, // destination HDC
rt_scroll.left, // dest upper left corner X
rt_scroll.top, // dest upper left corner Y
rt_scroll.right-rt_scroll.left+1, // width of dest rectangle
rt_scroll.bottom-rt_scroll.top+1, // height of dest rectangle
memdc, // source HDC
0, // source upper left corner X
0, // source upper left cornet Y
SRCCOPY
);
SelectObject(memdc, hOldBitMap);
DeleteObject (membit);
DeleteDC (memdc);
ReleaseDC (hwndScroll, hdcScroll);

Setting a windows region without disabling theming

Does anyone know how to assign a window region (SetWindowRgn or Control.Region in WinForms) without killing the theming in the non-client area?
For example, running the following generates a Windows 2000-style unthemed title bar, border, etc:
var form = new Form { Width=500, Height=500, BackColor = Color.Azure };
form.Text = "But soft, what light through yonder window breaks?";
var region = new Region (new Rectangle (Point.Empty, form.Size));
region.Exclude (new Rectangle (100, 100, 300, 300));
form.Region = region;
form.ShowDialog();
I'm guessing it's to do with this MSDN article which says:
As long as a window has a non-NULL
region applied to it (SetWindowRgn),
the UxTheme Manager assumes that this
is a specialized window and the window
will not use visual styles.
...hence UxThemes assumes it's a specialized window. Is there a way to tell the UxTheme Manager explicitly to theme a window?
The answer to your question is that you cannot.
But a workaround, to give you a transparent section in your form, would be to add the WS_EX_LAYERED extended window style to your form. Then you can tell the Window Manager that you want to use a chroma-color key to make part of your form transparent:
SetLayeredWindowAttributes(
Form.Handle, // __in HWND hwnd,
RGB(0, 255, 0), //green is the color key __in COLORREF crKey,
255, //window is opaque otherwise __in BYTE bAlpha,
LWA_COLORKEY //use color-key (rather than per-pixel alpha) __in DWORD dwFlags
);
Then you can put your "transparent" area as lime green:
Which then at runtime will be transparent:
Update: When i use layered window to have full transparency mouse events do trickle through to what's underneath. Notice the "flag" icon highlight:
See also
Window Overview -> Window Features -> Layered Windows
SetLayeredWindowAttributes Function
Extended Window Styles
Layered Windows

Skin Dialogs when using XP Themes?

I have been skinning dialogs by using the WM_CTLCOLORSTATIC, WM_CTLCOLORBTN messages as such:-
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORBTN:
hdc = (HDC)wParam;
hwndCtl = (HWND)lParam;
SetTextColor(hdc,RGB(0xff,0xff,0xff));
SetBkMode(hdc,TRANSPARENT);
pt.x = 0;
pt.y = 0;
MapWindowPoints(hwndCtl,_hwnd,&pt,1);
x = -pt.x;
y = -pt.y;
SetBrushOrgEx(hdc,x,y,NULL);
return (INT_PTR)_skinBrush;
This code sets the text color to white for all static elements as the background brush paints a low contrast image.
Ive (only) recently updated to use Common Controls 6 and the XP-Themeing look on my dialogs but all the text on controls has 'dissapeared' as its being drawn in the default black again.
Is there some other way to control the text color of controls under xp-themeing? Or do I need to consider ownerdraw now :-( ?
(And owner draw is really NOT an option - If I ownerdraw all my controls the entire motivation for switching to common controls 6 in the first place falls away).

QT: Scroll widget that renders directly to the DC

I'm trying to create a widget which paints directly to the windows Device Context by calling getDC() and painting an HBITMAP to it.
The widget I'm painting resides inside a scroll widget.
I've implemented the paintEvent() and it does seem to paint but immediatly after painting the widget gets painted over again with a blank gray color.
I've tried setting WA_PaintOnScreen and Qt::WA_NoSystemBackground but none of those help.
In theory this should be possible since this is basically how the GLWidget works.
What am I missing?
Found the answer here:
http://www.qtchina.net/qt4c++guiprogramming/ch20lev1sec1.html/
void GdiControl::paintEvent(QPaintEvent * /* event */)
{
RECT rect;
GetClientRect(winId(), &rect);
HDC hdc = GetDC(winId());
FillRect(hdc, &rect, HBRUSH(COLOR_WINDOW + 1));
SetTextAlign(hdc, TA_CENTER | TA_BASELINE);
TextOutW(hdc, width() / 2, height() / 2, text.utf16(), text.size());
ReleaseDC(winId(), hdc);
}
For this to work, we must also
reimplement
QPaintDevice::paintEngine() to return
a null pointer and set the
Qt::WA_PaintOnScreen attribute in the
widget's constructor.

Resources