I created window with this window styles:
WS_CLIPCHILDREN | WS_POPUP | WS_BORDER | WS_SIZEBOX | WS_VISIBLE.
But for unknown reason WS_CLIPSIBLINGS style is automatically added.
Do you somebody know reason for this?
Sample code:
hWnd = CreateWindowExW(0, szWindowClass, szTitle, WS_CLIPCHILDREN | WS_POPUP | WS_BORDER | WS_SIZEBOX | WS_VISIBLE, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
Only child windows are mentioned in the MSDN.
Clips child windows relative to each other; that is, when a particular
child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style
clips all other overlapping child windows out of the region of the
child window to be updated. If WS_CLIPSIBLINGS is not specified and
child windows overlap, it is possible, when drawing within the client
area of a child window, to draw within the client area of a
neighboring child window.
Actually, All overlapped and popup-style windows have WS_CLIPSIBLINGS properties. That is to say, you can't get rid of WS_CLIPSIBLINGS attributes and draw in its overlapping brothers'windows.
If it's just a child window, you can add WS_CLIPSIBLINGS yourself.
Add WS_CLIPSIBLINGS
After redrawing
Related
I want to create buttons with custom shapes so I decided to do it with the help of Layered Windows. I create window for button, set bitmap for it, make it layered and then try to make white color fully transparent. As soon as I write on masm, the code looks like this:
mov button, rv(CreateWindowEx, WS_EX_APPWINDOW or WS_EX_LAYERED,
chr$("Button"), NULL,
WS_CHILD or BS_BITMAP or WS_VISIBLE,
300, 10, 81, 98,
hWin, 200, hInstance, NULL)
mov bmHandle, rv(LoadImage, NULL, bitmapPath,
IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE or LR_DEFAULTSIZE)
invoke SendMessage, button, BM_SETIMAGE, IMAGE_BITMAP, eax
invoke SetLayeredWindowAttributes, hWnd, 00000000h, 0, LWA_COLORKEY
But white color on bitmap does not become transparent though it worked with custom window shape for me.
How can I make this work?
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);
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
I'm trying to make an MFC window (a CDialog) go fullscreen whenever the user attempts to maximize it. The window is being used as an OpenGL context. I'm attempting to do everything inside of the CDialog::OnSize callback. Here's the code that I'm using:
void MyCDialogSubclass::OnSize(UINT action, int width, int height) {
CDialog::OnSize(action, width, height);
switch (action) {
case SIZE_MAXIMIZED:
if (GetStyle() & WS_OVERLAPPEDWINDOW) {
MONITORINFO screen;
screen.cbSize = sizeof(screen);
if (GetMonitorInfo(MonitorFromWindow(GetSafeHwnd(), MONITOR_DEFAULTTOPRIMARY), &screen)) {
ModifyStyle(WS_OVERLAPPEDWINDOW, 0, 0);
width = screen.rcMonitor.right - screen.rcMonitor.left;
height = screen.rcMonitor.bottom - screen.rcMonitor.top;
SetWindowPos(&wndTop, screen.rcMonitor.left, screen.rcMonitor.top, width, height, SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
}
break;
case SIZE_MINIMIZED:
case SIZE_RESTORED:
if (!(GetStyle() & WS_OVERLAPPEDWINDOW)) {
ModifyStyle(0, WS_OVERLAPPEDWINDOW, 0);
SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
break;
}
if (wglMakeCurrent(my_hdc, my_hglrc))
my_opengl_reshape_call(width, height);
wglMakeCurrent(NULL, NULL);
}
If I comment out the ModifyStyle() calls, everything works fine, with the obvious proviso that the window style stays normal, so there's a standard window title bar across the top of the screen that I want to get rid of. If I keep the ModifyStyle() calls and comment out the SetWindowPos() calls, the title bar and everything else disappears, but the window has a black region along the top of the screen that is the exact height of the title bar—as though it is being reserved. If I don't comment out either of the pairs of calls, as shown in the code above, the screen flickers violently. I believe it's flickering back and forth between the black region being present and not being present, but it's difficult to tell. This flickering also appears to corrupt video memory, as I get persistent artifacts in window title bars (in different applications, no less) and, once, the login picture in the Start menu was replaced with one of my OpenGL textures.
The code that I'm using is adapted from the code that Stefan linked in an answer below, from The Old New Thing, which is working better than my original code. I'm assuming this problem isn't arising from my decision not to insert code to save the window placement (per The Old New Thing), because this happens before I ever try to restore the window.
Don't maximize the window if you want it to be full screen.
Use this approach instead.
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.