i've searched for a solution but I didn't find any solution. In native Win32 it is possible to make the clientarea of a framedwindow transparent:
HWND hwnd = (HWND)GetHandle();
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED|WS_EX_TOOLWINDOW);
SetLayeredWindowAttributes(hwnd, RGB(255,255,255), 0, LWA_COLORKEY);
Refresh();
This works with wxwidgets too. It makes the clientarea transparent too. But now the windows form isn't clickable.
I've tried to put this code in the paint-event-method "TestFrame::OnPaint(wxPaintEvent& event)" and in the method "TestFrame::TestFrame(wxWindow* parent,wxWindowID id)".
I only need to make the titlebar clickable to move the window around.
Thank you in advance.
It is probably a bad idea to mix windows API calls in with wxWidgets code.
Have you tried wxWindow::SetTransparent ( wxByte alpha ) ?
http://docs.wxwidgets.org/trunk/classwx_window.html#ac8cf4398cec50ac36634760f45a0656f
try
HWND hwnd = (HWND)GetHandle();
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED|WS_EX_TOOLWINDOW);
SetLayeredWindowAttributes(hwnd, RGB(255,255,0), 0, LWA_COLORKEY);
and set the backgroundcolor=yellow
Maybe the problem was your choice to use rgb(255,255,255). If you use RGB(255,255,0). It works.
Related
I try use SetWindowPos,But someone told me it was wrong to do that.
WIN32 program , How to top window in WIN8/WIN10 ?
like the Task Manager。
Two ways to make a window "top most".
When you create the window with CreateWindowEx, specify WS_EX_TOPMOST as an extended style.
CreateWindowEx(WS_EX_TOPMOST, ...);
For an existing window, use SetWindowPos:
DWORD flags = SWP_NOMOVE | SWP_NOSIZE;
SetWindowPos(hwnd, HWND_TOPMOST, 0,0,0,0, flags);
Either way is fine.
There are several ways to do this using .NET (take this for instance), yet I wasn't able to reproduce the same thing using only C++ win32.
My approach was to use WS_EX_LAYERED and then SetLayeredWindowAttributes to have some control over the opacity, but I read more and I found out that WS_EX_TRANSPARENT is 'better'- it allows click-through.
However, using
hWnd = CreateWindowEx(WS_EX_TRANSPARENT, fooName, fooName, WS_OVERLAPPEDWINDOW | WS_POPUP | WS_CLIPSIBLINGS, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
doesn't seem to do the trick. There is also another thing: once I get the click-through window working, can I use
PostMessage(hWnd, WM_LBUTTONUP, 0, MAKELPARAM(GET_X_LPARAM(lParam) ,GET_Y_LPARAM(lParam)));
to block the dragging state from passing through?
Note: the dragging state is produced using a touchpad device.
The click-through part:
Indeed, WS_EX_TRANSPARENT by itself is a big lie; so I used WS_EX_COMPOSITED | WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST instead.
I have control over the opacity using SetLayeredWindowAttributes(hWnd, 0, (255 * opacity) / 100, LWA_ALPHA); (quite unorthodox, but it works) and I also use
SetCapture(hWnd);
ShowCursor(false);
to grab the mouse focus as the top level window doesn't let go and hides the cursor.
I also tried to force the focus on the window adding WM_NCACTIVATE and WM_ACTIVEAPP:
case WM_MOUSEMOVE:
fprintf(stdout, "Mouse move [%d][%d]\n", GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
SetForegroundWindow(hWnd);
break;
case WM_LBUTTONDOWN:
printf("Mouse click\n");
SetForegroundWindow(hWnd);
break;
case WM_NCACTIVATE:
return false;
case WM_ACTIVATEAPP:
wActive = (bool)wParam;
if(wActive == false)
return 0;
else
return DefWindowProc(hWnd, message, wParam, lParam);
The dragging part:
In my particular case I wanted to 'poke' the window underneath (child window) without losing focus; unfortunately, any mouse click event will change the focus to that child window - a solution would be to:
set a timer (SetTimer, WM_TIMER) and check whether your application lost focus or not
set a hook to your window and reply to a WM_KILLFOCUS message with a WM_SETFOCUS message
I have been lately working on creating windows with transparency and click-through properties and I just tried this:
HWND hWnd = CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT, cName, wTitle, NULL, 0, 0, 640, 480, NULL, 0, GetModuleHandle(NULL), 0);
You can't close it, minimize it, drag it, etc - every click you make goes straight through as if it didn't exist.
Then just change transparency using:
SetLayeredWindowAttributes(hWnd, 0, 100, LWA_ALPHA);
It achieves everything that in your question, if I understood it correctly.
Your approach might have not worked because WS_EX_LAYERED must be defined if you use WS_EX_TRANSPARENT.
I have to hide popup windows in third party library.
I have implemented windows hook stuff with SetWindowsHookEx and know all the newely created hWnd(s). I listen to HSHELL_WINDOWCREATED callback and do the following:
long style= GetWindowLong(hWnd, GWL_STYLE);
style &= ~(WS_VISIBLE); // this works - window become invisible
style |= WS_EX_TOOLWINDOW; // flags don't work - windows remains in taskbar
style &= ~(WS_EX_APPWINDOW);
SetWindowLong(hWnd, GWL_STYLE, style);
What I do wrong here to hide newely created windows in task bar?
Before you use SetWindowLong, call ShowWindow(hWnd, SW_HIDE), then call SetWindowLong, then call ShowWindow again like ShowWindow(hWnd, SW_SHOW). So your code will look like this:
long style= GetWindowLong(hWnd, GWL_STYLE);
style &= ~(WS_VISIBLE); // this works - window become invisible
style |= WS_EX_TOOLWINDOW; // flags don't work - windows remains in taskbar
style &= ~(WS_EX_APPWINDOW);
ShowWindow(hWnd, SW_HIDE); // hide the window
SetWindowLong(hWnd, GWL_STYLE, style); // set the style
ShowWindow(hWnd, SW_SHOW); // show the window for the new style to come into effect
ShowWindow(hWnd, SW_HIDE); // hide the window so we can't see it
Here is a relevant quote from Microsoft's Website:
To prevent the window button from being placed on the taskbar, create
the unowned window with the WS_EX_TOOLWINDOW extended style. As an
alternative, you can create a hidden window and make this hidden
window the owner of your visible window.
The Shell will remove a window's button from the taskbar only if the
window's style supports visible taskbar buttons. If you want to
dynamically change a window's style to one that doesn't support
visible taskbar buttons, you must hide the window first (by calling
ShowWindow with SW_HIDE), change the window style, and then show the
window.
You must use GWL_EXSTYLE to get/set the EX flags, GWL_STYLE will not work for EX flags.
I was wondering if it's possible to remove the border and caption of a window. I have done this before but I cannot recall what style I used.
Also, how would you go about to make your own UI with fully resizable components. I'm working in C++ at the moment. An example of this "custom UI" would be kinda like Winamp so I'm wondering if this is possible in C++ (with any library or alike).
To create window without caption & border just set style to WS_POPUP instead of WS_OVERLAPPED when create your window:
CreateWindow(szWindowClass, szTitle, WS_POPUP, x, y, width, height, NULL, NULL, hInstance, NULL);
Im using mfc to draw a custom menu except it has a nasty looking border around it. How do i get rid of the border or draw over it?
For example:
(the white border around the edge)
Edit:
i know its only three hours left but none of the things below work. I have tried them using the following code:
HWND hwnd = m_pParent->getBrowserHWND();
uint32 style = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, style&~WS_BORDER);
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED);
HookHwnd hook(hwnd);
int res = TrackPopupMenu((HMENU)menu.GetHMenu(), TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD|TPM_RECURSE, xPos, yPos, 0, hwnd, NULL);
SetWindowLong(hwnd, GWL_STYLE, style);
Actually further to freefallr's advice it may well just be a simple WS_BORDER.
Try removing it using:
ModifyStyle( WS_BORDER, 0, SWP_FRAMECHANGED );
I only use WTL for UI coding, it's been years since I've looked at MFC, but it's also very close to the Windows API. You might check the creation flags for the menu.
Call GetWindowLong and specifically, check GWL_EXSTYLE for WS_EX_CLIENTEDGE; this may be the cause of your problem. You can always OR it out and call SetWindowLong and redraw the menu to test.
Hope this is of some help!
Update:
I wonder if the frame isn't being updated. Try:
ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);