Capture of Window - Page 9
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 9 of 9 FirstFirst ... 6789
Results 121 to 130 of 130

Thread: Capture of Window

  1. #121
    Join Date
    May 2014
    Posts
    149

    Re: Capture of Window

    Arjay: but the code was working, there was no problem with the callback function. I just added the wrect thing in the main function.

    GetWindowRect(hwnd, &wrect);
    Code:
    if (CODE>82)	{
    const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    const int fudgex = 0;
    }
    This causes error. I don't see any relation between the callback function and this code, except that in callback there is the rectw used too.

    One error was unknown identifier rectw and should be wrect used in main. But this does not solve the problem.
    Last edited by crazy boy; May 16th, 2014 at 01:59 PM.

  2. #122
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,392

    Re: Capture of Window

    Code:
    const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    rectw hasn't been defined.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #123
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,392

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    Arjay: but the code was working, there was no problem with the callback function. I just added the wrect thing in the main function.

    GetWindowRect(hwnd, &wrect);
    Code:
    if (CODE>82)	{
    const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    const int fudgex = 0;
    }
    This causes error. I don't see any relation between the callback function and this code, except that in callback there is the rectw used too.

    Edit
    OK solved. I don't know the relation and why this type of error. But the following error was unknown identifier rectw and should be wrect used in main.
    callback uses wrect, not rectw!
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  4. #124
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,392

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    Why am I getting error?
    ...
    If I remove all from if (CODE>82) till the end except ending curly bracket it succeeds to compile otherwise
    '&' : check operator precedence for possible error; use parentheses to clarify precedence

    Something with rect, rectw declaration?
    Or perhaps, something with "curly bracket"?
    Victor Nijegorodov

  5. #125
    Join Date
    May 2014
    Posts
    149

    Re: Capture of Window

    Corrected code 85 on my way (calculation by 2kaud):
    Code:
    // CODE 81 and 82 de facto no difference
    #define	CODE		85 // 81
    #define	WINDOW_MIN_HEIGHT		200
    #define	WINDOW_MAX_HEIGHT	700
    #define	WINSTYLE		0x14FF0000
    
    // #define	IS_CHILD	TRUE  // [TRUE | FALSE | 0] ... 0 - deactivates this detection
    // GetWindowLong: GWL_HWNDPARENT
    
    #include <windows.h>
    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <tchar.h>
    #include <conio.h>
    using namespace std;
    
    const int maxstr = 200;
    // const char wndtitle[] = "AOK";
    LONG t1; LONG t2;
    RECT rect, wrect;
    int fudgex, fudgey;
    struct windata {
    	static const string titles[]; // only static const integral data members can be initialized within a class
    	static const string default;
    	string choose;
    	HWND hfnd; // Found destination window handler
    };
    const string windata::titles[] = {"learn", "dialog", "aok", "map" };
    const string windata::default = "learn"; // windata.default = ... will produce syntax error : missing ';' before '.'
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    char *ch = title;
    
    GetWindowRect(hwnd, &wrect); // Calculate window height
    int winHeight = wrect.bottom-wrect.top;
    if ( (WINDOW_MIN_HEIGHT && winHeight<WINDOW_MIN_HEIGHT) || 
    	 (WINDOW_MAX_HEIGHT && winHeight>WINDOW_MAX_HEIGHT))
    		return TRUE; // skip window
    
    if ( GetWindowLong(hwnd, GWL_STYLE) & WINSTYLE	!= TRUE )
    		return TRUE;
    
    	/*	GetWindowTextA - copies the text of the specified window's 
    	title bar (if it has one) into a buffer. If the specified window is a
    	control, the text of the control is copied. However, it
    	can't retrieve the text of a control in another application. */
    	
    if (GetWindowTextA(hwnd, title, maxstr)) {
    		for (char *ch = title; *ch; ++ch) // was ch++)
    			*ch = (char)tolower(*ch);		
    		 // strstr - finds the first occurrence of a substring within a string. The comparison is case-sensitive.
    		 // c_str - converts the contents of a string as a C-style, null-terminated string.
    		if (strstr(title, ((windata*)lparam)->choose.c_str())) {
    			((windata*)lparam)->hfnd = hwnd;
    			SetLastError(ERROR_NO_MATCH);
    			cout << "Found matching window - " << title << endl;
    			return FALSE;
    		}		
    	}
    	return TRUE;
    } // Press F5 to continue debug, not F10. Otherwise "error" occurs.
    
    int main()
    {
    // HWND HCapture = GetForegroundWindow();
    /* HWND HCapture = FindWindow(NULL, _T("Learning WInAPI")); // get window handle
    */
    windata wd;
    cout << "Partial window title: ";
    getline(cin, wd.choose);
    wd.choose.erase(wd.choose.find_last_not_of(" \n\r\t")+1); // trim string
    if ( wd.choose == "" )  // select default window
    	wd.choose = wd.default;
    
    
    /* EnumWindows(in,in) - Enumerates all top-level windows on the
    screen by passing the handle to each window, in turn, to 
    callback function. EnumWindows continues until the last top-level
    window is enumerated or the callback function returns FALSE. 
    The EnumWindows function does not enumerate child windows.
    */
    
    	if (EnumWindows(EnumWindowsProc, (LPARAM)&wd) || (GetLastError() != ERROR_NO_MATCH)) {
    		cout << "Cannot find window\n";
    		return 1;
    	}
    
    	HWND HCapture = wd.hfnd;
    
    	if (!IsWindow(HCapture)) {
    		cout << "Bad find! Cannot find window\n";_getch();return 2;
    	}
    
    #if CODE<85
    	fudgey = (GetMenu(HCapture)?GetSystemMetrics(SM_CYMENU):0) 
    					+ GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYSIZEFRAME);
    	fudgex = 0;
    #endif
    
    GetClientRect(HCapture, &rect);
    LONG dx = rect.right - rect.left;
    LONG dy = rect.bottom - rect.top;
    
    if (CODE>82)	{
    					/*
    const int fudgey = (GetMenu(HCapture)?GetSystemMetrics(SM_CYMENU):0) 
    					+ GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYSIZEFRAME);
    					*/
    					fudgey = (wrect.bottom - wrect.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    					fudgex = 0;
    }
    	
    // create BITMAPINFO structure
    // used by CreateDIBSection
    BITMAPINFO info = {0};
    
    	info.bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
    	info.bmiHeader.biWidth         = dx + fudgex;
    	info.bmiHeader.biHeight        = dy + fudgey;
    	info.bmiHeader.biPlanes        = 1;
    	info.bmiHeader.biBitCount      = 24;
    	info.bmiHeader.biCompression   = BI_RGB;
    
    HDC	HDevice = CreateCompatibleDC(NULL);
    //HDC HDevice = GetDC(HCapture);
     
    BYTE*	memory = 0;
     
    HBITMAP	HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, NULL, NULL);
    
    	SelectObject(HDevice, HBitmap);
     
    	SendMessage(HCapture, WM_PRINTCLIENT, 0, 0);
    	// SendMessage(HCapture, WM_PRINTCLIENT,(WPARAM) HDevice, 0);
    	if (!PrintWindow(HCapture, HDevice, /*PW_CLIENTONLY*/0))
    		return 2;
    
    	SendMessage(HCapture, WM_PRINTCLIENT, 0, 0);
    
    	ReleaseDC(HCapture, HDevice);
    
    char *buffer = new char[50];
    
    	sprintf(buffer, "capture%d%d.bmp", dx, dy);
    
    ofstream file(buffer, ios::binary);
    
    	if (!file) {
    		DeleteObject(HBitmap);
    		return 1;
    	}
    
    // initialize bitmap file headers
    BITMAPFILEHEADER fileHeader = {0};
    BITMAPINFOHEADER infoHeader = {0};
    
    	fileHeader.bfType      = 0x4d42;
    	fileHeader.bfSize      = 0; //????
    	fileHeader.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    
    	infoHeader.biSize          = sizeof(infoHeader);
    	infoHeader.biWidth         = dx + fudgex;
    	infoHeader.biHeight        = dy;
    	infoHeader.biPlanes        = 1;
    	infoHeader.biBitCount      = 24;
    	infoHeader.biCompression   = BI_RGB;
    
    	// save file headers
    	file.write((char*)&fileHeader, sizeof(fileHeader));
    	file.write((char*)&infoHeader, sizeof(infoHeader));
    
    // save 24-bit bitmap data
    int wbytes = (((24 * (dx) + 31) & (~31)) / 8);
    int tbytes = wbytes * dy;
    
    	file.write((char*)(memory), tbytes);
    	file.close();
    
    	// delete bitmap
    	DeleteObject(HBitmap);
    	return 0;
    
    }
    Result:
    So there are big spaces still


    BTW: Can you describe the calculation?
    Code:
    LONG dy = rect.bottom - rect.top;
    fudgey = (wrect.bottom - wrect.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    What is -2? Do you mean border? My border does not look like 2 px.

    My window edge has 4 pixels total:

    Idk what it is. Maybe doubled border with padding and margin :-)
    Last edited by crazy boy; May 16th, 2014 at 02:16 PM.

  6. #126
    Arjay's Avatar
    Arjay is offline Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,295

    Re: Capture of Window

    Don't use globals. Look..., in your callback, you need to get the rect of the current window, so just declare a local rect variable and use it inside the callback.

    Using a global doesn't save you anything and it only causes grief later (because as the program grows in complexity, it becomes more difficult to find out where the global variable was changed).

    An important programming concept to learn is encapsulation along with controlling variable scope.

  7. #127
    Join Date
    May 2014
    Posts
    149

    Re: Capture of Window

    I know, but I thought that is the bug. I wanted to use local here and there but the bug occurred.
    I don't know how to solve it if I should not to make the global. The bug "operator precedence" will be there!!!

    What is what on the pics bellow:
    Theme:


    Apply:
    The wide area in map window was not captured, but it is up same as in the left


    It is same for inactive and active border....

    That's all. So I don't know how the style is defined. But looks the border has at least 3 pixels in this case. One px is the highlight or shadow, then there is the gray area which is 1px in my case, in the image above is 15px and there are 1 and 1 pixel between the frames

    I still don't know what numbers you operate with. What parts of the images are included in your calculation?
    Last edited by crazy boy; May 16th, 2014 at 02:43 PM.

  8. #128
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,392

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post

    Result:
    So there are big spaces still


    BTW: Can you describe the calculation?
    Code:
    LONG dy = rect.bottom - rect.top;
    fudgey = (wrect.bottom - wrect.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    What is -2? Do you mean border? My border does not look like 2 px.

    My window edge has 4 pixels total:

    Idk what it is. Maybe doubled border with padding and margin :-)
    This is to do with the 'fudge' factor I talked about in some of my previous posts. PrintWindow() doesn't seem to do what is required or work as documented (see previous posts) so I attempted to manipulate the captured image to only save the client part and not the non-client part which is also returned with PrintWindow(). The fudgex and fudegy values were guesstimates as to what needs to be done to the image from PrintWindow() to only get the client area and as I said previously is a 'kludge' that I don't like and the values are 'try it and see'. The area at the top to remove is basically the difference between the size of the overall window and the size of the client area together with the size of two window borders (top and bottom) [note not 2 px but subtract 2 times frameheight]. This assumes that the window to be captured is a normal overlapped type window. If the window to be captured is of a different type, then you'll need to try different values for fudgex and fudgey until you get the result required. Also as I said previously, you will need to look everywhere dx and dy are used to determine if fudgex and fludgey are needed. Also, if he result is not as required, then again you'll just need to try different values for fudgex and fudgey until you get somewhere near what you want. Yes, as I said before I don't like it but unless any other guru knows how to get PrintWindow() to do what is required I don't know another way using this function.

    Incidentally, as it is very obvious that PrintWindow() isn't providing what you want and workarounds are just nasty 'kludges', why persist in using it? Why not use other methods of capturing the client area of a window as per links previously provided?
    Last edited by 2kaud; May 16th, 2014 at 02:46 PM.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  9. #129
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,392

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    I know, but I thought that is the bug. I wanted to use local here and there but the bug occurred.
    I don't know how to solve it if I should not to make the global. The bug "operator precedence" will be there!!!
    What you are trying to do is use the result of GetWindowRect() called in the enum function back in the main function when a window has been found. If you want to do this, then put wrect as part of the windata struct. It is considered good programming style/practice to only have const variables (ie ones that don't change) at global scope.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  10. #130
    Join Date
    May 2014
    Posts
    149

    Re: Capture of Window

    I still don't understand the concept of "start point" where the capture is calculated from. Does the PrintWindow() take middle of the window as "start point?". Let's have window which has 10px width and 10px height. it has 4 pixels at bottom and 4 pixels at top.
    Let's have title area 24 px height. I move the window to coords 14,38. So the Print calculates the "start point" in the middle?
    It calculates x=7 because 14/2 for? And y then 14/2+24=31? If the point is in the middle of the window that makes sense to me. Because all we have is width and height:
    Code:
    info.bmiHeader.biWidth         = dx + fudgex;
    info.bmiHeader.biHeight        = dy + fudgey;
    This give us approximate calculation because there can be either even or odd height.

    But in the case that they have the beginning point in the top left corner of the window that does not make sense to me at all. Because in that case your data which you calculate could not effect the position of the capture area, only its width and height. So we could always start own capture in same position, but changing position of the right and bottom side of the "cut" area.
    Last edited by crazy boy; May 17th, 2014 at 12:48 AM.

Page 9 of 9 FirstFirst ... 6789

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center