I'm trying to change console size with WinApi, i have succeded changing the size of the window etc but when i print to the console i dont get all information printed in the console window and i cant understand why this is happening? When i remove the resizing code everything works fine. I think the issue is related to that the size of the console buffer is to small.
SetConsoleSize(int, int) is called first in main.
#include <iostream>
#include <stdexcept>
#include <windows.h>
static void SetConsoleSize(int x, int y) {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle("Title!");
COORD coordinates;
coordinates.X = x;
coordinates.Y = y;
SMALL_RECT windowRect;
windowRect.Top = 0;
windowRect.Left = 0;
windowRect.Bottom = x - 1;
windowRect.Right = y - 1;
// Adjust buffer size:
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (!SetConsoleScreenBufferSize(handle, coordinates))
throw std::runtime_error("Unable to resize screen buffer.");
// display as a maximized window
ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
}
Information in window was overwriten since the buffer for console window was two small, see COORD coordinates which decide the size of the console window buffer.
Solution code below, observe that different screen sizes can cause issue since there is no code for eval screen size only origin {0,0} as start position:
static void SetConsoleSize() {
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle("Title);
CONSOLE_SCREEN_BUFFER_INFO sbInfo;
GetConsoleScreenBufferInfo(hStdOut, &sbInfo);
COORD coordinates;
coordinates.X = 80; // size of line.
coordinates.Y = 1000; //Number of lines.
SMALL_RECT windowRect;
windowRect.Top = 0;
windowRect.Left = 0;
windowRect.Bottom = 40;
windowRect.Right = 79;
//set textbuffer size
assert(SetConsoleScreenBufferSize(hStdOut, coordinates));
//change window size.
assert(SetConsoleWindowInfo(hStdOut, true, &windowRect));
const HWND hwnd = GetConsoleWindow();
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE); //Positioning the window
}
Related
The title pretty much explains it all after using MoveWindow function the window does go to the second monitor tho after minimizing the app and opening it again the window appears back on the first screen. I'm guessing there is a function to like say to windows the window is now on second screen not the first tho I can't seem to find it.
RECT applicationRect;
HWND applicationHWND;
applicationHWND = GetForegroundWindow();
GetWindowRect(applicationHWND, &applicationRect);
const int width = abs( abs(applicationRect.right) - abs(applicationRect.left) );
const int height = abs( abs(applicationRect.bottom) - abs(applicationRect.top) );
short screen = 0;
if(applicationRect.left < -8){//Posible left screen
if(abs(applicationRect.left) > abs(applicationRect.right))screen = 1;
else screen = 0;
}
const int newleft = (screen == 0)*(applicationRect.left - 1920) + (screen == 1)*(applicationRect.left + 1920);
MoveWindow(applicationHWND, newleft, applicationRect.top, width, height, false);
This is the function that moves window to another screen.
Now I can reproduce it, this happens when the target window is maximized. In this case MoveWindow cannot change the normal position value(that is, WINDOWPLACEMENT.rcNormalPosition). When the window is restored to the maximize, it will be restored based on this value(detect it in which monitor). You need to check whether the window is maximized first, and then call SetWindowPlacement to change this Position. In addition to maximized windows, you can use SetWindowPlacement instead of MoveWindow.
#include <windows.h>
#include <iostream>
int main()
{
RECT applicationRect;
HWND applicationHWND;
BOOL ret = 0;
applicationHWND = GetForegroundWindow();
GetWindowRect(applicationHWND, &applicationRect);
const int width = abs(abs(applicationRect.right) - abs(applicationRect.left));
const int height = abs(abs(applicationRect.bottom) - abs(applicationRect.top));
short screen = 0;
if (applicationRect.left < -8) {//Posible left screen
if (abs(applicationRect.left) > abs(applicationRect.right))screen = 1;
else screen = 0;
}
const int newleft = (screen == 0) * (applicationRect.left - 1920) + (screen == 1) * (applicationRect.left + 1920);
WINDOWPLACEMENT place = {};
place.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(applicationHWND, &place);
if (place.showCmd == SW_SHOWMAXIMIZED)
{
MoveWindow(applicationHWND, newleft, applicationRect.top, width, height, false);
}
place.rcNormalPosition.left = (screen == 0) * (place.rcNormalPosition.left - 1920) + (screen == 1) * (place.rcNormalPosition.left + 1920);
place.rcNormalPosition.right = (screen == 0) * (place.rcNormalPosition.right - 1920) + (screen == 1) * (place.rcNormalPosition.right + 1920);
place.flags |= WPF_ASYNCWINDOWPLACEMENT;
ret = SetWindowPlacement(applicationHWND, &place);
}
I am capturing particular portion of desktop window in a bitmap and trying to print
BGR pixel color value. This captured portion of desktop window is completely filled with 16, 0, 16 color.
When I capture and print the data when my window color depth is 32 everything is right,
but if my window is in 24/16 bit color mode then I am getting different pixel values instead of 16, 0, 16.
I am capturing screen left = 150, top = 150, right = 200, bottom = 200.
*********CAPTURING AN IMAGE FROM DESKTOP*********
iLeft = 150;
iTop = 150;
iRight = iLeft + 50;
iBottom = iTop + 50;
/*
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(hWnd);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if(!hdcMemDC)
{
MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
RECT rcClient;
GetClientRect(hWnd, &rcClient);
//This is the best stretch mode
SetStretchBltMode(hdcWindow,HALFTONE);
//The source DC is the entire screen and the destination DC is the current window (HWND)
if(!StretchBlt(hdcWindow,
0,0,
rcClient.right, rcClient.bottom,
hdcScreen,
0,0,
GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN),
SRCCOPY))
{
MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK);
goto done;
}
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, rcClient.bottom-rcClient.top);
if(!hbmScreen)
{
MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK);
goto done;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);
// Bit block transfer into our compatible memory DC.
if(!BitBlt(hdcMemDC,
0,0,
rcClient.right-rcClient.left, rcClient.bottom-rcClient.top,
hdcWindow,
0,0,
SRCCOPY))
{
MessageBox(hWnd, L"BitBlt has failed", L"Failed", MB_OK);
goto done;
}
// Get the BITMAP from the HBITMAP
GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbitmap.
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
// A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile(L"captureqwsx.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//Offset to where the actual bitmap bits start.
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfHeader.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfHeader.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
CloseHandle(hFile);
//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL,hdcScreen);
ReleaseDC(hWnd,hdcWindow);
return 0;
*/
//#if 0
HDC hdcScreen;
// HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
HRGN rgn = NULL;
BITMAP bmpScreen;
// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
//hdcWindow = GetDC(hWnd);
//if(g_hdcMemDC == NULL)
{
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcScreen);
if(!hdcMemDC)
{
//MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
//RECT rcClient;
//GetClientRect(hWnd, &rcClient);
//This is the best stretch mode
SetStretchBltMode(hdcMemDC,HALFTONE);
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcScreen, iRight - iLeft, iBottom - iTop);
if(!hbmScreen)
{
//MessageBox(hWnd, L"CreateCompatibleBitmap Failed",L"Failed", MB_OK);
goto done;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC,hbmScreen);
}
//The source DC is the entire screen and the destination DC is the current window (HWND)
/* if(!StretchBlt(hdcWindow,
0,0,
rcClient.right, rcClient.bottom,
hdcScreen,
0,0,
GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN),
SRCCOPY))
{
MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK);
goto done;
}
*/
// Bit block transfer into our compatible memory DC.
if(!StretchBlt(hdcMemDC,
0,0,
iRight - iLeft,
iBottom - iTop,
hdcScreen,
iLeft,iTop,
iRight - iLeft,
iBottom - iTop,
SRCCOPY))
{
// MessageBox(hWnd, L"StretchBlt has failed",L"Failed", MB_OK);
goto done;
}
}
*******************FUNCTION FOR GETTING THE BITMAP RAW DATA POINTER***********
BYTE* Get24BitPixels(HDC dcDesktop, HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight, WORD * pReminderWidth)
{
// a bitmap object just to get bitmap width and height
BITMAP bmpBmp;
// pointer to original bitmap info
LPBITMAPINFO pbmiInfo;
// bitmap info will hold the new 24bit bitmap info
BITMAPINFO bmiInfo;
// width and height of the bitmap
WORD wBmpWidth ; WORD wBmpHeight;
// ---------------------------------------------------------
// get some info from the bitmap
// ---------------------------------------------------------
GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
pbmiInfo = (LPBITMAPINFO)&bmpBmp;
//get width and height
wBmpWidth = (WORD)pbmiInfo->bmiHeader.biWidth;
int iReminderWidth = (wBmpWidth%4);
//wBmpWidth -= (wBmpWidth%4); // width is 4 byte boundary aligned.
wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
// copy to caller width and height parms
*pwWidth = wBmpWidth;
*pwHeight = wBmpHeight;
wBmpWidth += (4 - iReminderWidth); // width is 4 byte boundary aligned, thereby increasing the width
//so that it will be fully divible by four , it will cause some extra bytes to be filled in with garbage value
//beyond the actual width of the bitmap, we will be discrading this extra padding pixels data while processign each pixel.
*pReminderWidth = 4 - iReminderWidth;
// ---------------------------------------------------------
// allocate width * height * 24bits pixels
BYTE * pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
if (!pPixels) return NULL;
// get user desktop device context to get pixels from
//HDC hDC = GetWindowDC(NULL);
// fill desired structure
bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmiInfo.bmiHeader.biWidth = wBmpWidth;
bmiInfo.bmiHeader.biHeight = -wBmpHeight;
bmiInfo.bmiHeader.biPlanes = 1;
bmiInfo.bmiHeader.biBitCount = 24;
bmiInfo.bmiHeader.biCompression = BI_RGB;
bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
bmiInfo.bmiHeader.biXPelsPerMeter = 0;
bmiInfo.bmiHeader.biYPelsPerMeter = 0;
bmiInfo.bmiHeader.biClrUsed = 0;
bmiInfo.bmiHeader.biClrImportant = 0;
// get pixels from the original bitmap converted to 24bits
int iRes = GetDIBits(dcDesktop,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
// release the device context
//ReleaseDC(NULL,hDC);
// if failed, cancel the operation.
if (!iRes)
{
delete [] pPixels;
pPixels = NULL;
return NULL;
};
// return the pixel array
return pPixels;
}
Fortunately I got the below mention post on StackOverflow.
Many thanks to Vodemki who posted this answer.
Get Pixel color fastest way?
I'm getting the problem my sprites leave a trail behind when i move them.
Tried drawning a BG with every refresh but then it start flickering.
This is what i do
// ...
int main(int argc, char *argv[])
{
BITMAP *buffer = NULL;
BITMAP *graphics = NULL;
buffer = create_bitmap(SCREEN_W, SCREEN_H);
graphics = load_bitmap("my_graphics.bmp", NULL);
clear_to_color(screen, makecol(0, 0, 0));
clear_to_color(buffer, makecol(0, 0, 0));
while(!key[KEY_ESC])
{
// ...
render_map(100,100);
// ...
}
}
void render_map(int w, int h)
{
// ...
for(int i=0;i < w * h;i++)
{
masked_blit(graphics, buffer, 0, 0, pos_x, pos_y, 32, 32);
}
// ...
blit(buffer, screen, camera_x,camera_y,0,0,SCREEN_W, SCREEN_H);
clear_to_color(buffer, makecol(0, 0, 0));
}
Thanks in advance for any help
Your code is a little hard to read, and you've left out big pieces of it. So it's hard to say for sure, but this line looks suspicious:
blit(buffer, screen, camera_x,camera_y,0,0,SCREEN_W, SCREEN_H);
When using a buffer, you typically will always be calling it like:
blit(buffer, screen, 0,0, 0,0, SCREEN_W,SCREEN_H);
and that is the only time you ever draw to the screen. So the steps are:
clear the buffer (by drawing a background image, tileset, color, etc)
draw everything to the buffer
copy the buffer to the screen
repeat
I'm currently making an application using processing intended to take an image and apply 8bit style processing to it: that is to make it look pixelated. To do this it has a method that take a style and window size as parameters (style is the shape in which the window is to be displayed - rect, ellipse, cross etc, and window size is a number between 1-10 squared) - to produce results similar to the iphone app pxl ( http://itunes.apple.com/us/app/pxl./id499620829?mt=8 ). This method then counts through the image's pixels, window by window averages the colour of the window and displays a rect(or which every shape/style chosen) at the equivalent space on the other side of the sketch window (the sketch when run is supposed to display the original image on the left mirror it with the processed version on the right).
The problem Im having is when drawing the averaged colour rects, the order in which they display becomes skewed..
Although the results are rather amusing, they are not what I want. Here the code:
//=========================================================
// GLOBAL VARIABLES
//=========================================================
PImage img;
public int avR, avG, avB;
private final int BLOCKS = 0, DOTS = 1, VERTICAL_CROSSES = 2, HORIZONTAL_CROSSES = 3;
public sRGB styleColour;
//=========================================================
// METHODS FOR AVERAGING WINDOW COLOURS, CREATING AN
// 8 BIT REPRESENTATION OF THE IMAGE AND LOADING AN
// IMAGE
//=========================================================
public sRGB averageWindowColour(color [] c){
// RGB Variables
float r = 0;
float g = 0;
float b = 0;
// Iterator
int i = 0;
int sizeOfWindow = c.length;
// Count through the window's pixels, store the
// red, green and blue values in the RGB variables
// and sum them into the average variables
for(i = 0; i < c.length; i++){
r = red (c[i]);
g = green(c[i]);
b = blue (c[i]);
avR += r;
avG += g;
avB += b;
}
// Divide the sum of the red, green and blue
// values by the number of pixels in the window
// to obtain the average
avR = avR / sizeOfWindow;
avG = avG / sizeOfWindow;
avB = avB / sizeOfWindow;
// Return the colour
return new sRGB(avR,avG,avB);
}
public void eightBitIT(int style, int windowSize){
img.loadPixels();
for(int wx = 0; wx < img.width; wx += (sqrt(windowSize))){
for(int wy = 0; wy < img.height; wy += (sqrt(windowSize))){
color [] tempCols = new color[windowSize];
int i = 0;
for(int x = 0; x < (sqrt(windowSize)); x ++){
for(int y = 0; y < (sqrt(windowSize)); y ++){
int loc = (wx+x) + (y+wy)*(img.width-windowSize);
tempCols[i] = img.pixels[loc];
// println("Window loc X: "+(wx+(img.width+5))+" Window loc Y: "+(wy+5)+" Window pix X: "+x+" Window Pix Y: "+y);
i++;
}
}
//this is ment to be in a switch test (0 = rect, 1 ellipse etc)
styleColour = new sRGB(averageWindowColour(tempCols));
//println("R: "+ red(styleColour.returnColourScaled())+" G: "+green(styleColour.returnColourScaled())+" B: "+blue(styleColour.returnColourScaled()));
rectMode(CORNER);
noStroke();
fill(styleColour.returnColourScaled());
//println("Rect Loc X: "+(wx+(img.width+5))+" Y: "+(wy+5));
ellipse(wx+(img.width+5),wy+5,sqrt(windowSize),sqrt(windowSize));
}
}
}
public PImage load(String s){
PImage temp = loadImage(s);
temp.resize(600,470);
return temp;
}
void setup(){
background(0);
// Load the image and set size of screen to its size*2 + the borders
// and display the image.
img = loadImage("oscilloscope.jpg");
size(img.width*2+15,(img.height+10));
frameRate(25);
image(img,5,5);
// Draw the borders
strokeWeight(5);
stroke(255);
rectMode(CORNERS);
noFill();
rect(2.5,2.5,img.width+3,height-3);
rect(img.width+2.5,2.5,width-3,height-3);
stroke(255,0,0);
strokeWeight(1);
rect(5,5,9,9); //window example
// process the image
eightBitIT(BLOCKS, 16);
}
void draw(){
//eightBitIT(BLOCKS, 4);
//println("X: "+mouseX+" Y: "+mouseY);
}
This has been bugging me for a while now as I can't see where in my code im offsetting the coordinates so they display like this. I know its probably something very trivial but I can seem to work it out. If anyone can spot why this skewed reordering is happening i would be much obliged as i have quite a lot of other ideas i want to implement and this is holding me back...
Thanks,
I am trying to write a program to play a full screen PC game for fun (as an experiment in Computer Vision and Artificial Intelligence).
For this experiment I am assuming the game has no underlying API for AI players (nor is the source available) so I intend to process the visual information rendered by the game on the screen.
The game runs in full screen mode on a win32 system (direct-X I assume).
Currently I am using the win32 functions
#include <windows.h>
#include <cvaux.h>
class Screen {
public:
HWND windowHandle;
HDC windowContext;
HBITMAP buffer;
HDC bufferContext;
CvSize size;
uchar* bytes;
int channels;
Screen () {
windowHandle = GetDesktopWindow();
windowContext = GetWindowDC (windowHandle);
size = cvSize (GetDeviceCaps (windowContext, HORZRES), GetDeviceCaps (windowContext, VERTRES));
buffer = CreateCompatibleBitmap (windowContext, size.width, size.height);
bufferContext = CreateCompatibleDC (windowContext);
SelectObject (bufferContext, buffer);
channels = 4;
bytes = new uchar[size.width * size.height * channels];
}
~Screen () {
ReleaseDC(windowHandle, windowContext);
DeleteDC(bufferContext);
DeleteObject(buffer);
delete[] bytes;
}
void CaptureScreen (IplImage* img) {
BitBlt(bufferContext, 0, 0, size.width, size.height, windowContext, 0, 0, SRCCOPY);
int n = size.width * size.height;
int imgChannels = img->nChannels;
GetBitmapBits (buffer, n * channels, bytes);
uchar* src = bytes;
uchar* dest = (uchar*) img->imageData;
uchar* end = dest + n * imgChannels;
while (dest < end) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest += imgChannels;
src += channels;
}
}
The rate at which I can process frames using this approach is much too slow. Is there a better way to acquire screen frames?
As a general method, I would hook the buffer-flipping function calls so I can capture the framebuffer on every frame.
http://easyhook.codeplex.com/