一种更改控制台窗口大小的方法

来源:互联网 发布:鼓楼西剧场 知乎 编辑:程序博客网 时间:2024/06/10 03:45

         有时在进行控制台编程的时候需要更改控制台窗口的大小,但是初学者往往不知所措,花了好长时间都解决不了这个问题。

         在这个提供一种方法,可以有效的更改控制台窗口大小。

         首先看一下更改窗口大小的函数:

BOOL WINAPI SetWindowPos(  _In_      HWND hWnd,  _In_opt_  HWND hWndInsertAfter,  _In_      int X,  _In_      int Y,  _In_      int cx,  _In_      int cy,  _In_      UINT uFlags);/*参数说明:hWnd [in]    A handle to the window.hWndInsertAfter [in, optional]    A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values.    ValueMeaning    HWND_BOTTOM    (HWND)1    Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.    HWND_NOTOPMOST    (HWND)-2    Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.    HWND_TOP    (HWND)0    Places the window at the top of the Z order.    HWND_TOPMOST    (HWND)-1    Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated. X [in]    The new position of the left side of the window, in client coordinates.Y [in]    The new position of the top of the window, in client coordinates.cx [in]    The new width of the window, in pixels.cy [in]    The new height of the window, in pixels. uFlags [in]    The window sizing and positioning flags. This parameter can be a combination of the following values.    ValueMeaning    SWP_ASYNCWINDOWPOS    0x4000    If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.    SWP_DEFERERASE    0x2000    Prevents generation of the WM_SYNCPAINT message.    SWP_DRAWFRAME    0x0020    Draws a frame (defined in the window's class description) around the window.    SWP_FRAMECHANGED    0x0020    Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.    SWP_HIDEWINDOW    0x0080    Hides the window.    SWP_NOACTIVATE    0x0010    Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).    SWP_NOCOPYBITS    0x0100    Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.    SWP_NOMOVE    0x0002    Retains the current position (ignores X and Y parameters).    SWP_NOOWNERZORDER    0x0200    Does not change the owner window's position in the Z order.    SWP_NOREDRAW    0x0008    Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.    SWP_NOREPOSITION    0x0200    Same as the SWP_NOOWNERZORDER flag.    SWP_NOSENDCHANGING    0x0400    Prevents the window from receiving the WM_WINDOWPOSCHANGING message.    SWP_NOSIZE    0x0001    Retains the current size (ignores the cx and cy parameters).    SWP_NOZORDER    0x0004    Retains the current Z order (ignores the hWndInsertAfter parameter).    SWP_SHOWWINDOW    0x0040    Displays the window.*/


        这个函数需要一个控制台窗口句柄,我们通过 FindWindow这个API函数获取窗口句柄,函数原型为:

HWND WINAPI FindWindow(  _In_opt_  LPCTSTR lpClassName,  _In_opt_  LPCTSTR lpWindowName);/*参数说明:lpClassName [in, optional]    The class name or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero.    If lpClassName points to a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, or any of the predefined control-class names.    If lpClassName is NULL, it finds any window whose title matches the lpWindowName parameter.lpWindowName [in, optional]    The window name (the window's title). If this parameter is NULL, all window names match.*/


         控制台窗口的类名为 ConsoleWindowClass ,而其窗口标题可以通过 GetConsoleTitle 来获取。至此,我们便可以编写更改窗口大小的代码了:

TCHAR szConsoleTitle[255];GetConsoleTitle(szConsoleTitle, 255);HWND hWnd = FindWindow(_T("ConsoleWindowClass"), szConsoleTitle);SetWindowPos(hWnd, HWND_TOP, 0, 0, 1500, 700, SWP_DRAWFRAME);

         但是我们很奇怪的是这样并没有达到我们想要的结果,为什么呢?因为控制台窗口有些特殊,要改变它的大小同时得更改它的屏幕缓冲区的大小,用到的函数为:SetConsoleScreenBufferSize,函数原型为:

BOOL WINAPI SetConsoleScreenBufferSize(  _In_  HANDLE hConsoleOutput,  _In_  COORD dwSize);/*参数说明:hConsoleOutput [in]    A handle to the console screen buffer. The handle must have the GENERIC_READ access right.dwSize [in]    A COORD structure that specifies the new size of the console screen buffer, in character rows and columns. The specified width and height cannot be less than the width and height of the console screen buffer's window. The specified dimensions also cannot be less than the minimum size allowed by the system. This minimum dependson the current font size for the console (selected by the user) and the SM_CXMIN and SM_CYMIN values returned by the GetSystemMetrics function.*/

         而hConsoleOutput的获取通过GetStdHandle函数,所以这部分的代码为:

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);COORD si = { 140, 30 };SetConsoleScreenBufferSize(hOut, si);

            这样便可以看到我们想要的效果了。

         需要说明的是, si.x * sizeof(FONT.WIDTH) 要小于等于cx, si.y * sizeof(FONT.HEIGHT) 要小于等于cy,这样才能完美的更改窗口大小,否则是不会出现我们想要的效果的。

         完整代码如下:

#include <windows.h>int _tmain(int argc, _TCHAR* argv[]){HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获得标准输出句柄COORD si = { 140, 30 };SetConsoleScreenBufferSize(hOut, si); // 设置屏幕缓冲区大小TCHAR szConsoleTitle[255];GetConsoleTitle(szConsoleTitle, 255);HWND hWnd = FindWindow(_T("ConsoleWindowClass"), szConsoleTitle);// 获得窗口句柄SetWindowPos(hWnd, HWND_TOP, 0, 0, 1500, 700, SWP_DRAWFRAME); // 设置窗口大小return 0;}




0 0
原创粉丝点击