I am using Dev C++ v5.6.1 IDE on Windows7.
I have written a C code which has hundreds of line that are displayed as output on screen.
The buffer size of Console Windows is small and I cannot view the initial printf statements.
I tried it changing from "properties" option, but it didn't help.
Where Can I find the option to increase the console window buffer size.
As you're using Windows, a simple way you can do this is by changing the console window size with the batch command: mode con: cols=150 lines=50. cols adjusts width, lines adjusts height.You may choose to call this with system to set the console size. This is considered bad, more about that here.
// This is considered bad, you shouldn't use system calls.
system("mode con: cols=150 lines=50");
A safer way to do this, is changing the buffer and size using functions defined in <windows.h>.
Here is a small example illustrating this:
#include <stdio.h>
#include <windows.h>
int main(void)
{
SMALL_RECT rect;
COORD coord;
coord.X = 150; // Defining our X and
coord.Y = 50; // Y size for buffer.
rect.Top = 0;
rect.Left = 0;
rect.Bottom = coord.Y-1; // height for window
rect.Right = coord.X-1; // width for window
HANDLE hwnd = GetStdHandle(STD_OUTPUT_HANDLE); // get handle
SetConsoleScreenBufferSize(hwnd, coord); // set buffer size
SetConsoleWindowInfo(hwnd, TRUE, &rect); // set window size
printf("Resize window");
return 0;
}
Keep in mind that the function SetConsoleWindowInfo fails if the specified window rectangle extends beyond the boundaries of the console screen buffer. More about that here.
Related
I created a code which change a certain pixels on the screen but when i want to change more pixels the performance of program will slow down.
You will see glitches and it's not that pretty as it should be.
Question:
How can i inprove performance of the code.
If I want to change more pixel or eventually all pixels on the screen.
I thought about using SETBITMAPBITS but I'm not sure how to it works. I have no experience with it.
Is there any other solution?
Example of my code: < Console app >
#define _WIN32_WINNT 0x601
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
HDC dng = GetDC(NULL);
while (true)
for (int i = 0; i <= 200; i++)
for (int j = 0; j <= 500; j++)
SetPixel(dng, i, j, RGB(0, 0, 255));
ReleaseDC(NULL, dng);
getchar();
}
If I understand correctly, you are trying to draw outside a window.
Every time you SetPixel you send a WM_PAINT message, which repaints the whole window.
That dramatically slows down your program. What you should do is use GDI, GDI+ or Direct2D to create a bitmap or a rectangle to then draw it at once.
Drawing outside a window is never a good idea. You have no control on what you just drew, and it will disappear when something interrupts it.
If you want a blue block without a title bar, create a layered window, then create a rectangle and draw it.
Microsoft's documentation might not be a tutorial, but it is informative.
Here is the Direct2D documentation:
https://learn.microsoft.com/en-us/windows/win32/direct2d/getting-started-with-direct2d
And here is how to create a layered window:
https://learn.microsoft.com/en-us/windows/win32/winmsg/window-features#layered-windows
Edit:
Comment said that SetPixel doesn't send WM_PAINT. What I am saying is SetPixel repaints the window.
[![enter image description here][1]][1]I am trying to capture the active window in Win32 using C++. With the BitBlt function I am able to capture, but once another window opens, the same window which I have already captured should only be captured. I don't want the other window which I have opened, it should be black. Can someone help with a solution?
https://www.codeproject.com/Articles/20367/Screen-Capture-Simple-Win32-Dialog-Based
void CaptureActiveWindow(void)
{
RECT ActWndRect;
WCHAR buf [100],buf1[20];
int xSrc=0,ySrc=-19;
int DepcWidth=10, DepcHeight=5;
OutputDebugString(L"Start capture act window ");
HDC ActWndDC = GetDC(hWndActWnd); //DC for the window you have clicked on
MemDC = CreateCompatibleDC(ActWndDC); //Memory DC Compatible with Above DC
GetWindowRect(hWndActWnd,&ActWndRect); //Will Store the Windows Are in Rectangle
wsprintf(buf,L"x1 = %d , y1 = %d, x2 = %d y2 =%d",ActWndRect.left,ActWndRect.top,ActWndRect.right,ActWndRect.bottom);
OutputDebugString(buf);
int Width = ActWndRect.right-ActWndRect.left; //Width of the Window
int Height =ActWndRect.bottom-ActWndRect.top; //Hight of the Window
if(GetWindowText(hWndActWnd,buf1,20) >0)
{
OutputDebugString(buf1);
}
if(CaptureControl)
{
ySrc= DepcWidth = DepcHeight = 0;
}
HBITMAP hBitmap = CreateCompatibleBitmap(DlgDC,Width-DepcWidth,Height-DepcHeight);//Will Create Bitmap Comatible With Our Window
SelectObject(MemDC,hBitmap);
BitBlt(MemDC,0,0,Width,Height,ActWndDC,xSrc,ySrc,SRCCOPY);//Will Copy the Window into MemDC
//BitBlt(DeskDC,110,110,Width,Height,MemDC,Begpt.x,Begpt.y,SRCCOPY);
SaveBitmap(MemDC, hBitmap,"Sample.bmp"); // will Save DC into .bmp File
ShowImage(); //Will Show u the .bmp File in MSPAINT.
}
Hook the mouse event Before sending active message to the window. Use WindowFromPoint to get the specified window(Hwnd). Then use GetWindowRect to get the window rect area. In this area, call WindowFromPoint for all the point in the rect, compare it with Hwnd(if it is a child window or not), and get the overlap RECT. After getting the bitmap of the capture window and then overwrites the black on the covered rect.
PS: I encounter BITMAPINFO error: Run-Time Check Failure #2 - Stack around the variable was corrupted.
Here provide a solution.
You can't capture the image of Chrome using BitBlt(), unless disable the Hardware Acceleration option of Chrome. But PrintWindow() works with PW_RENDERFULLCONTENT flag. When use it, the image in center will have a black border. While using PrintWindow (hWndActWnd,ActWndDC,0x00000003) align the image to the left.Then modify cx and cy of CreateCompatibleBitmap(), you can remove the border easily.
I was trying to get the height of the title bar of a specific window on Windows. You can replicate it with Notepad. I'm using C++ and none of the codes I found online yielded the correct result. Using e.g. Screenpresso I measured 31 pixels for my window bar height.
The functions I tried are the following:
TitleBarHeight.h:
#pragma once
#include <windows.h>
inline int get_title_bar_thickness_1(const HWND window_handle)
{
RECT window_rectangle, client_rectangle;
GetWindowRect(window_handle, &window_rectangle);
GetClientRect(window_handle, &client_rectangle);
return window_rectangle.bottom - window_rectangle.top -
(client_rectangle.bottom - client_rectangle.top);
}
inline int get_title_bar_thickness_2(const HWND window_handle)
{
RECT window_rectangle, client_rectangle;
GetWindowRect(window_handle, &window_rectangle);
GetClientRect(window_handle, &client_rectangle);
return (window_rectangle.right - window_rectangle.left - client_rectangle.right) / 2;
}
Results:
auto window_handle = FindWindow("Notepad", nullptr);
auto a = get_title_bar_thickness_1(window_handle); // 59
auto b = get_title_bar_thickness_2(window_handle); // 8
auto c = GetSystemMetrics(SM_CXSIZEFRAME); // 4
auto d = GetSystemMetrics(SM_CYCAPTION); // 23
Getting the system metrics with GetSystemMetrics() does not work because windows can have different title bar heights obviously and there is no argument for the window handle.
How can I really get the result of 31?
Assuming that you don't have menu bar, you can map points from client coordinate system to screen one
RECT wrect;
GetWindowRect( hwnd, &wrect );
RECT crect;
GetClientRect( hwnd, &crect );
POINT lefttop = { crect.left, crect.top }; // Practicaly both are 0
ClientToScreen( hwnd, &lefttop );
POINT rightbottom = { crect.right, crect.bottom };
ClientToScreen( hwnd, &rightbottom );
int left_border = lefttop.x - wrect.left; // Windows 10: includes transparent part
int right_border = wrect.right - rightbottom.x; // As above
int bottom_border = wrect.bottom - rightbottom.y; // As above
int top_border_with_title_bar = lefttop.y - wrect.top; // There is no transparent part
Got 8, 8, 8 and 31 pixels (96DPI aka 100% scaling setting)
You should also take into account DPI awareness mode. Especially GetSystemMetrics is tricky because it remembers state for System DPI when your application was launched.
Send a message WM_GETTITLEBARINFOEX to the window, and you will get the bounding rectangle of the title bar.
TITLEBARINFOEX * ptinfo = (TITLEBARINFOEX *)malloc(sizeof(TITLEBARINFOEX));
ptinfo->cbSize = sizeof(TITLEBARINFOEX);
SendMessage(hWnd, WM_GETTITLEBARINFOEX,0, (LPARAM)ptinfo);
int height = ptinfo->rcTitleBar.bottom- ptinfo->rcTitleBar.top;
int width = ptinfo->rcTitleBar.right - ptinfo->rcTitleBar.left;
free(ptinfo);
First, make sure your application is high DPI aware so that the system doesn't lie to you.
Options:
Trust GetSystemMetrics. Nearly any top-level window that actually has a different caption size is doing custom non-client area management which is going to make it (nearly) impossible. The obvious exception is a tool window (WS_EX_TOOLWINDOW) which probably has a SM_CYSMCAPTION height if the WS_CAPTION style is also set.
Get the target window rect and the target window's style. Use AdjustWindowRectEx to determine the size differences with the WS_CAPTION style toggled. I'm not sure if this will work because there may be some interaction between on whether you can have a caption without some kind of border.
Get the target window rect and send WM_HITTEST messages for coordinates that move down the window. Count how many of those get HT_CAPTION in return. Bonus points if you do this with a binary search rather than a linear search. This is probably the hardest and the most reliable way to do it, assuming the window has a rectangular caption area.
If I've understood correctly, it looks like you want to take the border size of the window (which we should be able to gather from the width as there is no title bar) and subtract it from the the verticle size minus the client window...
inline int get_title_bar_thickness(const HWND window_handle)
{
RECT window_rectangle, client_rectangle;
int height, width;
GetWindowRect(window_handle, &window_rectangle);
GetClientRect(window_handle, &client_rectangle);
height = (window_rectangle.bottom - window_rectangle.top) -
(client_rectangle.bottom - client_rectangle.top);
width = (window_rectangle.right - window_rectangle.left) -
(client_rectangle.right - client_rectangle.left);
return height - (width/2);
}
The code below calculates the size of a the rect holding the text to a checkbox. Code works fine when i'm using a stationary computer with monitors with different screen resolution. But when I run the exact same code on a laptop with an external monitor connected the box is too small. Laptop screen res is 1680x1050 and the monitor is 1920x1080.
pclRect has the same values no matter which computer I run it on.
Anybody's got an idea how to solve this?
Results:
void CForm::SetSize(CWnd *pCWnd, CRect *pclRect)
{
CDC *pclDC = m_pclPanel->GetDC();
CFont* font = pCWnd->GetFont();
LOGFONT logFont;
font->GetLogFont(&logFont);
CString str;
pCWnd->GetWindowText(str);//Get controller text
CClientDC dc(pCWnd);
dc.SelectObject(font);
int iWidth;
int iHeight;
long lFontSize = -MulDiv(logFont.lfHeight, GetDeviceCaps(pclDC->m_hDC, LOGPIXELSY), 72);
iWidth = dc.GetTextExtent(str).cx; //Get controller text length
iWidth += GetExtraWidth(); //This adds 18 to the width since it's the width of the checkbox itself
iHeight = abs(lFontSize) + GetExtraHeight();
pclRect->bottom = pclRect->top + iHeight;
pclRect->right = pclRect->left + iWidth;
pCWnd->MoveWindow(pclRect);
}
If target window is Vista or higher, use BCM_GETIDEALSIZE to find the minimum size. But check box cannot have multi-line flag (BS_MULTILINE). For example
m_checkBox.SetWindowText(L"long text xxx xxx xxx xxx xxx xxx");
SIZE sz;
if (Button_GetIdealSize(m_checkBox.m_hWnd, &sz) && sz.cx > 0 && sz.cy > 0)
{
m_checkBox.SetWindowPos(0, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE);
}
else
{
//use another method ...
}
Otherwise, modify your code and instead of supplying 18 pixels for checkbox width, use
GetSystemMetrics to find the check box width (this results in 15 pixels in default DPI, so you have to add few more pixels for text padding).
Use GetThemePartSize if theme is active. For example:
CClientDC dc(this);
SIZE sz;
HTHEME ht = OpenThemeData(m_hWnd, L"Button");
if (ht)
{
GetThemePartSize(ht, dc, BP_CHECKBOX, CBS_CHECKEDNORMAL, NULL, TS_TRUE, &sz);
CloseThemeData(ht);
//sz.cx is 13 pixels in default DPI
}
else
{
sz.cx = GetSystemMetrics(SM_CXMENUCHECK);
//sz.cx is 15 pixels in default DPI
}
Screen resolution is not relevant here. The posted images suggest that both displays have the same DPI settings. Note that if DPI settings changes, and your application is DPI aware then sz.cx will be different.
I have been checking out some Rogue like games (Larn, Rogue, etc) that are written in C and C++, and I have noticed that they do not have the scrollbars to the right of the console window.
How can I accomplish this same feature?
To remove the scrollbar, simply set the screen buffer height to be the same size as the height of the window:
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
// get handle to the console window
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
// retrieve screen buffer info
CONSOLE_SCREEN_BUFFER_INFO scrBufferInfo;
GetConsoleScreenBufferInfo(hOut, &scrBufferInfo);
// current window size
short winWidth = scrBufferInfo.srWindow.Right - scrBufferInfo.srWindow.Left + 1;
short winHeight = scrBufferInfo.srWindow.Bottom - scrBufferInfo.srWindow.Top + 1;
// current screen buffer size
short scrBufferWidth = scrBufferInfo.dwSize.X;
short scrBufferHeight = scrBufferInfo.dwSize.Y;
// to remove the scrollbar, make sure the window height matches the screen buffer height
COORD newSize;
newSize.X = scrBufferWidth;
newSize.Y = winHeight;
// set the new screen buffer dimensions
int Status = SetConsoleScreenBufferSize(hOut, newSize);
if (Status == 0)
{
cout << "SetConsoleScreenBufferSize() failed! Reason : " << GetLastError() << endl;
exit(Status);
}
// print the current screen buffer dimensions
GetConsoleScreenBufferInfo(hOut, &scrBufferInfo);
cout << "Screen Buffer Size : " << scrBufferInfo.dwSize.X << " x " << scrBufferInfo.dwSize.Y << endl;
return 0;
}
You need to make the console screen buffer the same size as the console window. Get the window size with GetConsoleScreenBufferInfo, srWindow member. Set the buffer size with SetConsoleScreenBufferSize().
Using #include <winuser.h>, you can simply do
ShowScrollBar(GetConsoleWindow(), SB_VERT, 0);
You can specify which scroll bar to hide using different parameters.
To remove scrollbars from the console, we can make the console screen buffer the same size as the console window. This can be done as follows:
#include <Windows.h>
#include <iostream>
int main() {
CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
// Get console handle and get screen buffer information from that handle.
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &screenBufferInfo);
// Get rid of the scrollbar by setting the screen buffer size the same as
// the console window size.
COORD new_screen_buffer_size;
// screenBufferInfo.srWindow allows us to obtain the width and height info
// of the visible console in character cells.
// That visible portion is what we want to set the screen buffer to, so that
// no scroll bars are needed to view the entire buffer.
new_screen_buffer_size.X = screenBufferInfo.srWindow.Right -
screenBufferInfo.srWindow.Left + 1; // Columns
new_screen_buffer_size.Y = screenBufferInfo.srWindow.Bottom -
screenBufferInfo.srWindow.Top + 1; // Rows
// Set new buffer size
SetConsoleScreenBufferSize(hConsole, new_screen_buffer_size);
std::cout << "There are no scrollbars in this console!" << std::endl;
return 0;
}