So, I'm using this for a game that starts as fullscreen.
I first do this to make it window mode:
SetWindowLongPtr(pantalla, GWL_STYLE, WS_CAPTION | WS_VISIBLE | WS_CLIPSIBLINGS | WS_SYSMENU);
SetWindowLongPtr(pantalla, GWL_EXSTYLE, WS_EX_WINDOWEDGE);
SetWindowPos(pantalla, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW);
After that I want to be able to hide the window, and to do so I'm using this:
SetWindowLongPtr(pantalla, GWL_EXSTYLE, WS_EX_NOACTIVATE);
SetWindowPos(pantalla, HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
That EX_NOACTIVATE was just a test, didn't work.
The problem is; the window hides perfectly, but then whenever I click (anywhere in the screen) the hidden program appears right back. How can I prevent that?
Related
I have a button and an EDIT window i named "textbox" initially. What i want to achieve is: when i press the button, the EDIT window's border will be remove and it's text is also changed. Here is how i initial them:
HWND textbox; //global variable
//in WM_CREATE:
CreateWindowEx(NULL, L"BUTTON", L"Remove border",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 10, 150, 40, hwnd,
(HMENU)IDC_TEXTBOX, NULL, NULL);
textbox = CreateWindowEx(
NULL, L"EDIT", NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE,
100, 100, 200, 100, hwnd, (HMENU) 0, NULL, NULL
);
SetWindowText(textbox, L"the initial text");
Since there is WS_BORDER in its style at the start, i thought removing it from window style will remove the border so this is my first attempt:
//In WM_COMMAND
case IDC_TEXTBOX: //if button is pressed
lStyle = GetWindowLongPtr(textbox, GWL_STYLE);
lStyle &= ~(WS_CHILD | WS_VISIBLE | ES_MULTILINE);
SetWindowLongPtr(textbox, GWL_STYLE, lStyle);
SetWindowPos(textbox, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOOWNERZORDER);
SetWindowText(textbox, L"how to remove the border around this text???");
break;
The code above didn't work. The window disappeared after i pressed the button. In the second attempt i followed the answer in this question:
case IDC_TEXTBOX:
lStyle = GetWindowLongPtr(textbox, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU);
SetWindowLongPtr(textbox, GWL_STYLE, lStyle);
lExStyle = GetWindowLongPtr(textbox, GWL_EXSTYLE);
lExStyle &= ~(WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE);
SetWindowLongPtr(textbox, GWL_EXSTYLE, lExStyle);
SetWindowPos(textbox, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE |
SWP_NOZORDER | SWP_NOOWNERZORDER);
SetWindowText(textbox, L"how to remove the border around this text???");
break;
This time, the text has changed but the border is still around after pressing the button:
so the question is: What did i do wrong in the 1st and 2nd attempt? And what should i do to remove the EDIT window border?
I would have made this a comment under your answer, but I don't have enough reputation.
Others in the comments have said that "Many of the system controls cache their initial styles and never update them" but strangely you can add a border after creation but just not remove it. So it seems that the border style is actually not cached.
My current solution is to recreate the control. Even though I can live with this solution (at the moment), I do not like it.
-Edit-
Never mind the above. I found that adding WS_BORDER after creation is actually a different border than the border added with WS_BORDER at creation. When you create the edit control with WS_BORDER and add WS_BORDER to it again with SetWindowLong() then the edit control now has 2 visible borders appearing as a single 2 pixel border. The WS_BORDER added after creation can be removed after creation but the initial WS_BORDER added at creation cannot be removed. So it appears that the initial edit border actually does get cached.
How can i move a control to top of the other when they have overlap together in windows API.
For example i create 2 buttons b1 and b2
HWND b1 = CreateWindow(L"BUTTON", L"button1", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
100, 100, 200, 50, my_Window_handle, (HMENU)100, NULL, NULL);
HWND b2 = CreateWindow(L"BUTTON", L"button2", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
50, 100, 250, 50, my_Window_handle, (HMENU)101, NULL, NULL);
I want to move b1 to top of the b2 or any control.
I used the function SetWindowPos as
SetWindowPos(b1, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
but id does not work correctly.
You don't want the child window to be top most, you want it to be at the top of the z-order. Like this:
SetWindowPos(b1, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
The documentation says for HWND_TOP:
Places the window at the top of the Z order.
Topmost will not work here because the child window must stay at the same z-order as its parent and SetWindowPos with HWND_TOPMOST as Hwnd_InsertAfter will try to change it. Only thing you need here is WS_CLIPSIBLINGS and then b1 will remain on top of b2.
b1 = CreateWindow(L"BUTTON", L"button1", WS_CHILD | WS_VISIBLE | WS_TABSTOP,
100, 100, 200, 50, hWnd, (HMENU)100, NULL, NULL);
b2 = CreateWindow(L"BUTTON", L"button2", WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_CLIPSIBLINGS, 50, 100, 250, 50, hWnd, (HMENU)101, NULL, NULL);
As well as setting the z-order, you need to set the WS_CLIPSIBLINGS style on the controls if they overlap, to stop them drawing over the top of each other.
I created a dialog using MFC Dialog application. This is using the dialog resource. And my resource file is as below
IDD_My_DIALOG DIALOGEX 0, 0, 233, 273
WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_OVERLAPPEDWINDOW | WS_EX_STATICEDGE | WS_EX_APPWINDOW
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 0, 0, 0x1Q
Now, at runtime I am receiving the dialog width and height. So as per the width and height I need to change this dialog size.
You can use the function call below:
MoveWindow(int x, int y, int Width, int Height);
Or, first get the Dialog coordinates:
CRect rc;
GetWindowRect(&rc); // getting dialog coordinates
MoveWindow(rc.left, rc.top, rc.Width(), rc.Height());
You can also use SetWindowPos() function.
I am trying to find out why my application has a small, few pixel, border.
My understanding is that WS_POPUP should take care of the problem;
DWORD wndExStyle = WS_EX_OVERLAPPEDWINDOW;
DWORD wndStyle = WS_POPUP | WS_SYSMENU;
g_hWnd = CreateWindowEx(wndExStyle, wcl.lpszClassName, L"junk",
wndStyle, 0, 0, 0, 0, 0, 0, wcl.hInstance, 0);
//Somewhere later
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
wglCreateContextAttribsARB(g_hDC, 0, attribList);
//Finally
ShowWindow(g_hWnd, SW_MAXIMIZE);
UpdateWindow(g_hWnd);
edit 1:
removed WS_BORDER
That border is caused by the use of WS_EX_OVERLAPPEDWINDOW. The fact that WS_EX_OVERLAPPEDWINDOW is defined as WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE makes it very clear what is going on.
Remove that extended style and the border goes away.
Including WS_BORDER in the style causes a thin border to be added to the window. Remove it from the style.
How do I capture key presses when a list view control has focus?
My window creation code looks like
// Window creation
HWND hwnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_APPWINDOW, g_szClassName, "Test", WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 209, 351, 0, 0, hInstance, 0);
HWND hwnd_list = CreateWindowEx(0, WC_LISTVIEW, "", WS_BORDER | WS_VISIBLE | WS_CHILD | WS_TABSTOP | LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | LVS_EX_FULLROWSELECT, 1, 246, 201, 55, hwnd, (HMENU)IDL_LISTVIEW, hInstance, 0);
Inside WndProc I process the WM_KEYPRESS message and create a MessageBox displaying the virtual code, but its only triggering when I press keys after clicking outside the list view.
You'll need to take a look at control subclassing, http://msdn.microsoft.com/en-us/library/bb773183%28VS.85%29.aspx.
If you're using MFC, it's a bit less painful. (Back in the day when Borland was still alive, it was a breeze in OWL, but that's ancient history.)
You need to subclass the listview proc and then use 'WM_KEYDOWN' to capture the input.