wxWidgets screenshot leaves most of image blank when applying to wxstaticbitmap - c++

When I tried capturing the wxwidgets screenshot, it doesn't showed any error. If I save it, it saves perfectly. But when I try to add it to a static bitmap, it just shows some icons and everything leaves transparent.
wxClientDC dcScreen(GetParent());
//Get the size of the screen/DC
wxCoord screenWidth, screenHeight;
dcScreen.GetSize(&screenWidth, &screenHeight);
//Create a Bitmap that will later on hold the screenshot image
//Note that the Bitmap must have a size big enough to hold the screenshot
//-1 means using the current default colour depth
screenshot.Create(screenWidth, screenHeight,-1);
//Create a memory DC that will be used for actually taking the screenshot
wxMemoryDC memDC;
//Tell the memory DC to use our Bitmap
//all drawing action on the memory DC will go to the Bitmap now
memDC.SelectObject(screenshot);
//Blit (in this case copy) the actual screen on the memory DC
//and thus the Bitmap
memDC.Blit( 0, //Copy to this X coordinate
0, //Copy to this Y coordinate
screenWidth, //Copy this width
screenHeight, //Copy this height
&dcScreen, //From where do we copy?
0, //What's the X offset in the original DC?
0 //What's the Y offset in the original DC?
);
//Select the Bitmap out of the memory DC by selecting a new
//uninitialized Bitmap
memDC.SelectObject(wxNullBitmap);
staticbitmap1->SetBitmap(screenshot);

In the wxStaticBitmap docs you can read:
Native implementations on some platforms are only meant for display of
the small icons in the dialog boxes.
If you want to display larger images portably, you may use generic
implementation wxGenericStaticBitmap declared in
.
It seems your screenshot is not small, and so the OS is messing you. Thus follow the advice and use wxGenericStaticBitmap

Related

How to get the handle of the active window in win32 using c++?

[![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.

How to display a image on a user defined rectangle with SDL_surface?

Im working on a project with my friend and we have run into an issue with surfaces and windows in SDL.
Currently we are able to create a window and display a rectangle on that window and move it around. The next thing we want to do is take a image and display it on a rectangle and then move it around the screen.
We started with taking the SDL_window* and turning it into SDL_surface* though this would take the image and display it on the background of the window.
Is there a way to turn a rectangle we create into a surface and display the image on that rectangle?
I have also tried using textures and it distorts the image when I tried to move it and the whole image doesn’t move with the rectangle.
// this happens in the constructor
temp_image_sur = IMG_Load( image_location.c_str() );
if( temp_image_sur == NULL )
{
std::cout << "Image could not be loaded" <<std::endl;
exit(1);
}
// This is in the actual draw function.
display_surface = SDL_GetWindowSurface( display_window );
if(display_surface == NULL )
{
printf(" null im exiting here %s\n", SDL_GetError());
exit(1);
}
image_surface = SDL_ConvertSurface( temp_image_sur, display_surface->format, 0 );
image_size = { this->location.x, this->location.y, this->size.width, this->size.height };
SDL_BlitSurface( image_surface, &image_size, display_surface, &image_size );
This is what we did for our first attempt, and the image was displaying on the base window. I believe I understand why it is displaying on the base window, it is because we are using that window as the surface, though I'm confused how do I make a user defined rectangle the surface?
We did try using SDL_CreateRGBSurface, though nothing is being displayed on the screen when we do this either.
display_surface = SDL_CreateRGBSurface(0, this->size.width, this->size.height, 1, this->color.red, this->color.green, this->color.blue, this->color.alpha);
Thanks guys!
Please let me know if there is anymore information you need, this is my first time posting and I tried to put all the info that I could think of.
Create a texture from your image surface by using SDL_CreateTextureFromSurface:
SDL_Texture* image_surface = SDL_CreateTextureFromSurface(renderer, temp_image_sur);
(remember to free it with SDL_DestroyTexture)
then use SDL_RenderCopy to draw it:
SDL_RenderCopy(renderer, image_texture, nullptr, &image_rect);
where image_rect is a SDL_Rect and the destination rectangle you want to draw your image to, for example:
SDL_rect image_rect = {10, 10, 200, 200};
To move your image simply change image_rect.x and/or image_rect.y

Can someone explain me the CDC::SelectObject to me?

http://msdn.microsoft.com/en-us/library/sa8ahz7h(v=vs.80).aspx
//Border
CPen pen;
pen.CreatePen(PS_DASH, 20, RGB(0, 0, 0));
CPen* penOld = dc.SelectObject(&pen);
dc.Rectangle(rect);
dc.FillRect(rect, &brush);
How does this code work? It draws a rectangle and then a border around it. I just can't get my head around it.
When you ask the device context to draw a rectangle, it will use the current Pen.
You can set the current Pen, Brush, clipping region or whatever using the SelectObject() method. You're basically saying "use this Pen from now on".
SelectObject() also returns the item it was using before, so that it doesn't get lost and leak memory, and you can put it back later if you want. This is why penOld is being saved to a variable in your code. It will probably be selected back again later on.
CPen pen; //declare a new Pen object
pen.CreatePen(PS_DASH, 20, RGB(0, 0, 0)); //Create the GDI Pen, dashed, 20 pixels wide, black.
CPen* penOld = dc.SelectObject(&pen); //Tell the DC to use this pen from now on.
dc.Rectangle(rect); //Draw a rectangle (using the current pen)
dc.FillRect(rect, &brush); //Fill a rectangle (using the current brush)
It creates a pen, selects it into the DC, and then instructs the DC to use the pen (which is 20 pixels wide) to draw a rectangle at the specified coordinates. It then fills in the inside of that rectangle with a brush.

Change SDL background

Is there any way to change the color of an empty SDL window to be white instead of black? I don't want to change any default settings. I'm just trying to change it for this particular program that I'm writing. I don't want to use an image file, but if I have to, I will.
I don't know if this matters, but I'm using SDL_SetVideoMode()
My code is very basic:
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
return 1;
SDL_Surface * screen = NULL;
screen = SDL_SetVideoMode(width, height, bpp, SDL_SWSURFACE);
SDL_FillRect(screen, NULL, 0xFFFFFF);
SDL_Delay(3000);
You need to call SDL_Flip for your changes to show up.
Acquire the surface from your Window using surf = SDL_SetVideoMode(...) and then do
SDL_FillRect(surf, NULL, 0xFFFFFF); // 0xFFFFFF = white in RGB, NULL = full window
SDL_Flip(surf);
You could use SDL_FillRect to fill the screen/a surface with your desired color.
You need to call SDL_UpdateRect after SDL_FillRect.

wxWidgets: Is there any way to avoid or to speed up wxBitmap::ConvertToImage()?

To get some smooth graphics, I want to draw oversampled by factor 2 and scale down afterwards.
So what I am doing is to draw oversampled on a wxBitmap in a wxMemoryDC, and then scale it down before copying to my dc. The code below works fine, but bitmapOversampled.ConvertToImage(); is extremely slow.
Is there any way to achieve the same without having to convert from wxBitmap to wxImage and vice versa?
void OnPaint
( wxPaintEvent& event )
{
wxBitmap bitmapOversampled(m_width * 2, m_height * 2);
wxMemoryDC memDC(bitmapOversampled);
// Draw the elements.
drawElements(&memDC);
// Scale to correct size.
wxImage image = bitmapOversampled.ConvertToImage();
image.Rescale(m_width, m_height);
memDC.SelectObject(wxBitmap(image));
// Copy to dc.
wxPaintDC dc(this);
dc.Blit(0, 0, m_width, m_height, &memDC, 0, 0);
};
Sadly, there is no portable wx method to do that scaling faster. But there is a Scale method in the Gtk port in wxBitmap. You can use that for wxGTK. For wxMSW, you can use StretchBlt of the win32 API. There are methods in wxDC that will provide you with the native HDC handle for Windows.
You can make it somewhat more straight forward if you draw directly:
wxPaintDC dc(this);
dc.DrawBitmap(image, 0, 0, false);
Also, don't recreate the bitmap in each paint event. Store it as a member, and recreate it only when you get a wxSizeEvent. It will probably considerably speed up your program.
Another way is to drop the scaling altogether and use wxGraphicsContext. It uses Cairo on wxGTK, and gdi+ on wxMSW. It's relatively new, but can draw antialiased.