C++ 如果过早获取窗口句柄,控制台窗口会被窃听。。?
我正在制作一个控制台应用程序,它必须是无边界的;为了实现这一点,我更改了控制台窗口样式和窗口区域,如下所示。C++ 如果过早获取窗口句柄,控制台窗口会被窃听。。?,c++,windows,winapi,console,console-application,C++,Windows,Winapi,Console,Console Application,我正在制作一个控制台应用程序,它必须是无边界的;为了实现这一点,我更改了控制台窗口样式和窗口区域,如下所示。 在某个时候,我遇到了一个问题,使得控制台窗口的大小通常约为2x1个字符,或者有时完全被窃听(不可见的客户端区域、部分白色、部分透明、随机边框等)。 有人告诉我添加ShowWindow(hWnd,SW_HIDE)到它现在所在的行可以解决问题。确实如此。 现在我想弄清楚为什么问题首先存在,还有没有其他方法来阻止呢 有人告诉我,问题可能会发生,因为Windows试图在我的程序运行的同时访问窗口
在某个时候,我遇到了一个问题,使得控制台窗口的大小通常约为2x1个字符,或者有时完全被窃听(不可见的客户端区域、部分白色、部分透明、随机边框等)。
有人告诉我添加
ShowWindow(hWnd,SW_HIDE)代码>到它现在所在的行可以解决问题。确实如此。
现在我想弄清楚为什么问题首先存在,还有没有其他方法来阻止呢
有人告诉我,问题可能会发生,因为Windows试图在我的程序运行的同时访问窗口属性(位置、样式、大小等)。不过,我不知道这是不是真的
#include <Windows.h>
#include <iostream>
int main()
{
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
SMALL_RECT srWnd = {0, 0, 1, 1};
SetConsoleWindowInfo(hCon, 1, &srWnd);
COORD cBuffSize = {81, 26};
SetConsoleScreenBufferSize(hCon, cBuffSize);
srWnd.Top = 0;
srWnd.Right = 80;
srWnd.Bottom = 25;
srWnd.Left = 0;
SetConsoleWindowInfo(hCon, 1, &srWnd);
// When the next two lines are moved so that they are the first two lines inside main(), the window gets bugged.
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd, SW_HIDE); // Or if you just remove this line
RECT rClnt;
GetClientRect(hWnd, &rClnt);
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
LONG exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
exStyle &= ~(WS_EX_CLIENTEDGE | WS_EX_APPWINDOW);
SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle | WS_EX_TOOLWINDOW);
rClnt.right += 1;
HRGN rgnClnt = CreateRectRgnIndirect(&rClnt);
SetWindowRgn(hWnd, rgnClnt, 1);
RECT rScrn;
GetWindowRect(GetDesktopWindow(), &rScrn);
SetWindowPos(hWnd, HWND_TOPMOST, rScrn.right / 2 - rClnt.right / 2, rScrn.bottom / 2 - rClnt.bottom / 2, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED);
ShowWindow(hWnd, SW_SHOW);
std::cin.get();
return 0;
}
#包括
#包括
int main()
{
句柄hCon=GetStdHandle(标准输出句柄);
SMALL_-RECT srWnd={0,0,1,1};
设置ConsoleWindowInfo(hCon、1和srWnd);
COORD cBuffSize={81,26};
设置控制台屏幕缓冲区大小(hCon、cBuffSize);
srWnd.Top=0;
srWnd.Right=80;
srWnd.Bottom=25;
srWnd.Left=0;
设置ConsoleWindowInfo(hCon、1和srWnd);
//当移动下两行以使其成为main()中的前两行时,窗口会被窃听。
HWND HWND=GetConsoleWindow();
ShowWindow(hWnd,SW_HIDE);//或者如果您只是删除这一行
RECT RCNT;
GetClientRect(hWnd和rClnt);
SetWindowLong(hWnd、GWL_样式、WS_弹出窗口);
LONG exStyle=GetWindowLong(hWnd,GWL_exStyle);
exStyle&=~(WS_EX_CLIENTEDGE | WS_EX_APPWINDOW);
SetWindowLongPtr(hWnd、GWL_EXSTYLE、EXSTYLE | WS_EX_TOOLWINDOW);
rClnt.right+=1;
HRGN rgnClnt=CreateRectRgnIndirect(&rClnt);
设置窗口rgn(hWnd,rgnClnt,1);
RECT-rScrn;
GetWindowRect(GetDesktopWindow(),&rScrn);
设置窗口位置(hWnd、hWnd_最上面、rScrn.right/2-RCNT.right/2、rScrn.bottom/2-RCNT.bottom/2、0、0、SWP_NOSIZE | SWP_框架已更改);
展示窗口(hWnd、SW_展示);
std::cin.get();
返回0;
}
以下是Windows 8的工作示例。但每次移动/调整/恢复控制台时,都需要刷新窗口区域
#include <windows.h>
#include <tchar.h>
#include <conio.h>
#include <dwmapi.h>
//#pragma comment(lib, "uxtheme.lib")
#pragma comment(lib, "dwmapi.lib")
int _tmain(int argc, _TCHAR* argv[])
{
HWND hWnd = GetConsoleWindow();
DWMNCRENDERINGPOLICY policy = DWMNCRP_DISABLED;
DwmSetWindowAttribute(hWnd, DWMWA_NCRENDERING_POLICY, &policy, sizeof(DWMNCRENDERINGPOLICY));
//SetThemeAppProperties(0);
//SetWindowThemeNonClientAttributes(hWnd, STAP_VALIDBITS, 0);
//SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED);
//RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
RECT rClnt, rWnd;
GetClientRect(hWnd, &rClnt);
GetWindowRect(hWnd, &rWnd);
POINT pt = {0,0};
MapWindowPoints(hWnd, NULL, &pt, 1);
OffsetRect(&rClnt, pt.x-rWnd.left, pt.y-rWnd.top);
HRGN rgnClnt = CreateRectRgnIndirect(&rClnt);
SetWindowRgn(hWnd, rgnClnt, 1);
_getch();
return 0;
}
#包括
#包括
#包括
#包括
//#pragma注释(lib,“uxtheme.lib”)
#pragma注释(lib,“dwmapi.lib”)
int _tmain(int argc,_TCHAR*argv[]
{
HWND HWND=GetConsoleWindow();
DWMNCRENDERINGPOLICY policy=DWMNCRP_已禁用;
DwmSetWindowAttribute(hWnd、DWMWA_NCRENDERING_POLICY和POLICY、sizeof(DWMNCRENDERINGPOLICY));
//设置EAPProperties(0);
//设置WindowTheMeNonClientAttributes(hWnd,STAP_有效位,0);
//设置窗口位置(hWnd、NULL、0、0、0、SWP|u NOSIZE | SWP|u NOMOVE | SWP|u NOZORDER | SWP|u FRAMECHANGED);
//重画窗口(hWnd,NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW);
RECT RCNT,rWnd;
GetClientRect(hWnd和rClnt);
GetWindowRect(hWnd和rWnd);
点pt={0,0};
MapWindowPoints(hWnd、NULL和pt,1);
偏斜(&RCNT,横截面x-rWnd.left,横截面y-rWnd.top);
HRGN rgnClnt=CreateRectRgnIndirect(&rClnt);
设置窗口rgn(hWnd,rgnClnt,1);
_getch();
返回0;
}