I create the static control with the code below:
hWnd = CreateWindowExW( 0,
L"STATIC",
Content.c_str(),
SS_LEFT | WS_VISIBLE | WS_CHILD /*| SS_SUNKEN*/,
200,
120,
120,
40,
hWndParent,
NULL,
hInstance,
NULL);
If I enable the SS_SUNKEN style in the creation code above, the created static control appears sunken successfully.
But, what I'm trying to do is the change the control style after its creation.
I tried this:
void BaseWindowClass::AddStyle(DWORD NewStyle)
{
// NewStyle = 0x00001000 = SS_SUNKEN
LONG oldstyle, changedstyle;
oldstyle=SetWindowLongW(hWnd, GWL_STYLE, changedstyle=GetWindowLongW(hWnd, GWL_STYLE) | NewStyle);
UpdateWindowStyles();
// oldstyle = 0x50000000
// changedstyle = 0x50001000 (everything looks normal)
}
void BaseWindowClass::UpdateWindowStyles()
{
BOOL success;
success=SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
// success = 0x00000001 (non-zero: SetWindowPos sucseeded)
}
Documentation:
SetWindowLong()
SetWindowPos()
I call SetWindowPos() after calling SetWindowLongW() because in the documentation of SetWindowLong, it says:
Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly.
And, in the documentation of SetWindowPos, it says:
If you have changed certain window data using SetWindowLong, you must call SetWindowPos for the changes to take effect. Use the following combination for uFlags: SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED.
Even after changing SetWindowLongW() and SetWindowPos() the style of my static control does not change.
What am I doing wrong, or what am I missing?
SS_SUNKEN effectively sets WS_EX_STATICEDGE in the extended styles (GWL_EXSTYLE) window long, so you can update GWL_EXSTYLE appropriately and reposition as you're currently doing.
Even though SS_SUNKEN does affect the frame of a static control, it isn't one of the "frame styles" that note is referring to.
That note refers to generic frame styles that affect all windows like WS_BORDER or WS_EX_CLIENTEDGE - styles that require a recalculation of a window's non-client area when changed.
Many of the system controls cache their styles upon creation and don't update the cache even if you change the styles via SetWindowLong. I would guess that's what's happening here - if you don't create the static control with SS_SUNKEN, you can't add it later. Your best option would be to simply destroy and recreate the control with the new style.
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.
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);
I have a Windows program which has two 2 windows in it:
hwnd (main interface)
hwnd2 (toplevel window, no parent, created by hwnd)
When I double click on hwnd, I need hwnd2 to pop up and show some data, so I use this function to bring hwnd2 to top:
BringWindowToTop(hwnd2);
hwnd2 is brought to top, but there is one thing odd. When I click on hwnd2 again, hwnd (main interface) pops itself up again automatically.
I tried to use the following function to solve this problem, but non of them works.
SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
BringWindowToTop(hwnd2); //This is the function brings hwnd2 to top
SetForegroundWindow(hwnd2); //doesn't work
SetWindowPos(hwnd2, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//doesn't work
SetWindowPos(hwnd2, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
// hwnd2 "always" on top, not what I want
SetActiveWindow(hwnd2); // doesn't work too (for replying to Magnus Skog, thanks)
SwitchToThisWindow(hwnd2, TRUE);// got the same problem with BringWindowToTop function
SwitchToThisWindow(hwnd2, FALSE);
How could I solve this problem?
Thanks in advance.
(for replying to aJ, hwnd2 doesn't have parent because it needs to be a toplevel window so it can be in front/back of other windows)
(hwnd2 is a media player which is composed of several windows, one of the windows is for video dispaly, two other trackbar controls for progress bar and volume bar, one Toolbar control for control panel.)
(There is one this might help, no matter which window I click on hwnd2, hwnd pops up automatically as loong as "the mouse is on top of hwnd in Z-order", including menu bar and non-client area, etc.)
(This media player is writen in Direct Show. I use IVideoWindow::put_Owner to put video window as the video owner, Direct Show internally creates a sub-video window as a child of the video window. Except for this sub-video window which I can't see the source code, I don't see any thing suspicious in hwnd2.)
I found the reason, which is because of Direct Show. I use multithread to execute it, and then the problem's solved. But...why??
This problem can be resolved by using PostMessage (rather than SendMessage).
try this,it is said coming from M$
HWND hCurWnd = ::GetForegroundWindow();
DWORD dwMyID = ::GetCurrentThreadId();
DWORD dwCurID = ::GetWindowThreadProcessId(hCurWnd, NULL);
::AttachThreadInput(dwCurID, dwMyID, TRUE);
::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
::SetWindowPos(m_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
::SetForegroundWindow(m_hWnd);
::SetFocus(m_hWnd);
::SetActiveWindow(m_hWnd);
::AttachThreadInput(dwCurID, dwMyID, FALSE);
In order to bring a window to top, you should get your window handle,thread handle, the windows thread handle who is in foreground
then we attach our thread to foreground window thread and get input by AttachThreadInput, then we set our window z order
to topmost and then restore its z order to normal, call SetForegroundWindow,SetFocus,SetActiveWindow to make sure our window is brought to top and is active and have focus
then deattach the input queue from the old foreground window thread, make our thread the only one who capture the input events
So why should We call AttachThreadInput, it is because
SetFocus sets the keyboard focus to the specified window. The window must be
attached to the calling thread's message queue.
What does AttachThreadInput do?
The AttachThreadInput function can be used to allow a set of threads
to share the same input state. By sharing input state, the threads
share their concept of the active window. By doing this, one thread
can always activate another thread's window. This function is also
useful for sharing focus state, mouse capture state, keyboard state,
and window Z-order state among windows created by different threads
whose input state is shared.
We use SetWindowPos to bring the windows to topmost and show the window if the window is hidding by using SWP_HIDEWINDOW
SetWindowPos function changes the size, position, and Z order of a
child, pop-up, or top-level window. These windows are ordered
according to their appearance on the screen. The topmost window
receives the highest rank and is the first window in the Z order
If your problem is your window is also minimized , you should add one line code to the end
ShowWindow(m_hWnd, SW_RESTORE);
Both work great:
::SetForegroundWindow(wnd)
or
::SetWindowPos(m_hWnd, // handle to window
HWND_TOPMOST, // placement-order handle
0, // horizontal position
0, // vertical position
0, // width
0, // height
SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE// window-positioning options
);
But remember that the last one sets the window always on top.
After many tries and errors.I found following solution to this problem:
SendMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); // restore the minimize window
SetForegroundWindow(hwnd);
SetActiveWindow(hwnd);
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
//redraw to prevent the window blank.
RedrawWindow(hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN );
The hwnd is your windows HWND . Please do not just copy and paste. You also need use GetLastError to check api error after every api call.
I have confirm following result on my win7:
Can restore minimize window and no error return.
If the window already top, the window title will blink and no error return.
If the window has closed, it will return the error "0x578 Invalid window handle."
It can bring the window to the top on all not top-most window and no error return.(For example it will behind the top-most taskmanager)
It do not make the window top-most. The user can make other window on top of it.
SwitchToThisWindow works best for me.
Have you tried SetActiveWindow()?
This will restore an app if minimized and bring it to the front:
ShowWindow(hWnd, SW_SHOW);
SetForegroundWindow(hWnd);
//work great!
Var
WndHandle:HWND;
begin
WndHandle :=FindWindowEx(0,0,nil,'Calculator');
PostMessage(WndHandle,WM_SHOWWINDOW,SW_RESTORE,0);
SetForegroundWindow(WndHandle);
end;