CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 8 of 9 FirstFirst ... 56789 LastLast
Results 106 to 120 of 132
  1. #106
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    Which function to use to detect if menu is present in the app? ...
    Menu is present in a window.
    Have a look at the GetMenu API or /and CWnd::GetMenu method in MSDN
    If only the main window contains a menu - you could use AfxGetMainWnd()->GetMenu();

    Quote Originally Posted by crazy boy View Post
    ... It's nonsense to recompile every time I change app. You also could help me if you would approve the code to support more titles. I am debugging 4 apps as target window: Learning WinAPI , Dialog App, AOK Trigger Studio and Map Viewer....
    Sorry, it's not clear what you mean.
    Victor Nijegorodov

  2. #107
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    OK, So I paste here the code to detect window from 2kaud. However it looks like freezing. On attempt to close the console window manually (mouse click on close button) it will generate access error, some kind of violent access to memory.

    This is shortened code. I want first to solve the Window detection and then I will continue to other codes. I meant if it were possible to detect one of those windows. I use at least 4 different application (titles of windows). Once I change destination app I need to recompile code. So if it were possible to simplify the job yet a bit more.
    Code:
    #define	CODE		81
    
    #include <windows.h>
    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <tchar.h>
    #include <conio.h>
    using namespace std;
    
    const int maxstr = 200;
    const char wndtitle[] = "AOK";
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    char *ch = title;
    
    	if (GetWindowTextA(hwnd, title, maxstr)) {
    		while (*ch = (char)tolower(*(ch++)));
    		 // strstr - finds the first occurrence of a substring within a string. The comparison is case-sensitive.
    		if (strstr(title, wndtitle)) {
    			*(HWND*)lparam = hwnd;
    			SetLastError(ERROR_NO_MATCH); // Sets the last-error code for the calling thread.
    			return FALSE;
    		}
    	}
    	return TRUE;
    }
    
    int main()
    {
    HWND HCapture;
    
    while (EnumWindows(EnumWindowsProc, (LPARAM)&HCapture));
    
    	if (GetLastError() != ERROR_NO_MATCH) {
    		cout << "Cannot find window\n";getch();return 1;
    	}
    
    	if (!IsWindow(HCapture)) {
    		cout << "Bad find! Cannot find window\n";getch();return 1;
    	}
    
    // GetSystemMetrics(SM_CYMENU) + 
    #if CODE==81	
    	const int fudgey = (GetMenu(HCapture)?GetSystemMetrics(SM_CYMENU):0) 
    					+ GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYSIZEFRAME);
    	const int fudgex = 0;
    #endif
    
    
    RECT rect;
    if (CODE == 81){
    	GetClientRect(HCapture, &rect);
    }
    LONG dx = rect.right - rect.left;
    LONG dy = rect.bottom - rect.top;
    }

  3. #108
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Capture of Window

    I've revised the code to ask for the partial name of the window rather than having it hard coded in the code. I've also changed the error testing.

    Code:
    #include <windows.h>
    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    const int maxstr = 200;
    
    struct windata {
    	string partitle;
    	HWND hfnd;
    };
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    
    char *ch = title;
    
    	if (GetWindowTextA(hwnd, title, maxstr)) {
    		while (*ch = (char)tolower(*(ch++)));
    
    		if (strstr(title, ((windata*)lparam)->partitle.c_str())) {
    			((windata*)lparam)->hfnd = hwnd;
    			SetLastError(ERROR_NO_MATCH);
    			cout << "Found matching window - " << title << endl;
    			return FALSE;
    		}
    	}
    
    	return TRUE;
    }
    
    int main()
    {
    windata wd;
    
    	cout << "Partial window title: ";
    	getline(cin, wd.partitle);
    
    	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\n";
    		return 2;
    	}
    
    RECT rect, rectw; 
    
    	GetClientRect(HCapture, &rect);
    	GetWindowRect(HCapture, &rectw);
    
    LONG dx = rect.right - rect.left;
    LONG dy = rect.bottom - rect.top;
    
    const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    const int 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);
     
    BYTE*	memory = 0;
     
    HBITMAP	HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, NULL, NULL);
    
    	SelectObject(HDevice, HBitmap);
     
    	if (!PrintWindow(HCapture, HDevice, /*PW_CLIENTONLY*/0))
    		return 2;
    
    	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;
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #109
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Capture of Window

    I've attached the zip of my test.exe version of the program (32bit) which works fine on several systems.

    testcomp.zip added created using compressed folder in xp.
    Attached Files Attached Files
    Last edited by 2kaud; May 14th, 2014 at 08:03 AM. Reason: Added textcomp.zip
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #110
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    OK, So I paste here the code to detect window from 2kaud. However it looks like freezing

    Code:
    while (EnumWindows(EnumWindowsProc, (LPARAM)&HCapture));
    Do you think the while loop above has anything to do with the freezing (or actually using 100% of the cpu)?

  6. #111
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    Arjay: There are maybe two bugs, even that 23kaud had tested it on his system and even XP SP3 without problems; #1 on my system XP SP3 the loop caused infinite loop. If I comment the loop it continues to debug successfully #2 on the end of enumerate callback function. This seems odd. It should be returned TRUE, but it did not returned even the debugger stepped on the return line.

    Ad #1 - bug removed with for loop:
    Code:
    for (char *ch = title; *ch; ++ch) // update: ch++ to ++ch
    	*ch = (char)tolower(*ch);
    Ad #2 - on stepping out of the callback - message is appeared:
    No source available. Call stack location user32.dll!7e37a4e8()

    Disambly:
    Code:

    7E37A4D3 jbe 7E37A4F7
    7E37A4D5 mov ecx,dword ptr [esi]
    7E37A4D7 call 7E3684E0
    7E37A4DC test eax,eax
    7E37A4DE je 7E37A4EF
    7E37A4E0 push dword ptr [ebp+14h]
    7E37A4E3 push dword ptr [esi]
    7E37A4E5 call dword ptr [ebp+10h]
    7E37A4E8 test eax,eax

    Yelllow marker pointed to 7E37A4E8 test
    Last edited by crazy boy; May 14th, 2014 at 04:48 AM.

  7. #112
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Capture of Window

    Quote Originally Posted by Arjay View Post
    Do you think the while loop above has anything to do with the freezing (or actually using 100% of the cpu)?
    Yeah, that was changed on a later post #108.

    I've also changed the case conversion code as OP had an issue with this in a PM. The code below has been compiled on 3 different version of MSVS and tested on several computers with no issues.

    Code:
    #include <windows.h>
    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    const int maxstr = 200;
    
    struct windata {
    	string partitle;
    	HWND hfnd;
    };
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    
    	if (GetWindowTextA(hwnd, title, maxstr)) {
    		for (char *ch = title; *ch; ++ch)
    			*ch = (char)tolower(*ch);
    
    		if (strstr(title, ((windata*)lparam)->partitle.c_str())) {
    			((windata*)lparam)->hfnd = hwnd;
    			SetLastError(ERROR_NO_MATCH);
    			cout << "Found matching window - " << title << endl;
    			return FALSE;
    		}
    	}
    
    	return TRUE;
    }
    
    int main()
    {
    	windata wd;
    
    	cout << "Partial window title: ";
    	getline(cin, wd.partitle);
    
    	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\n";
    		return 2;
    	}
    
    	RECT rect, rectw;
    
    	GetClientRect(HCapture, &rect);
    	GetWindowRect(HCapture, &rectw);
    
    	LONG dx = rect.right - rect.left;
    	LONG dy = rect.bottom - rect.top;
    
    	const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    	const int 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);
    
    	BYTE*	memory = 0;
    
    	HBITMAP	HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, NULL, NULL);
    
    	SelectObject(HDevice, HBitmap);
    
    	if (!PrintWindow(HCapture, HDevice, /*PW_CLIENTONLY*/0))
    		return 2;
    
    	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;
    }
    NOTE THIS IS ANSI CODE AND NOT UNICODE
    Last edited by 2kaud; May 14th, 2014 at 06:19 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #113
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    To make it clear. I don't say, that the window is not found, but that I cannot debug it because it will get error "no source available". My question here is: do you experience same problem? Is this normal? When you add break on the end of callback EnumWindowsProc(){ } do you got error?
    Last edited by crazy boy; May 14th, 2014 at 06:30 AM.

  9. #114
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    To make it clear. I don't say, that the window is not found, but that I cannot debug it because it will get error "no source available". My question here is: do you experience same problem? Is this normal? When you add break on the end of callback EnumWindowsProc(){ } do you got error?
    No, I have no problems. I can step though the code fine in the debugger and set break points etc which are triggered as expected. If you get errors whilst trying to debug it looks like you either haven't set the configuration to debug build or there is some issue with the build debug properties. Note that the file in post #109 has no debug info included with the .exe.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #115
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    To make it clear. I don't say, that the window is not found, but that I cannot debug it because it will get error "no source available". My question here is: do you experience same problem? Is this normal?
    Yes, it is normal. It is NOT an error. It only means that source code to the function form user32.dll that calls your callback is not available, so you can step in only in the assembly.
    Victor Nijegorodov

  11. #116
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    Quote Originally Posted by VictorN View Post
    Yes, it is normal. It is NOT an error. It only means that source code to the function form user32.dll that calls your callback is not available, so you can step in only in the assembly.
    Thanks for the info. But how I debug it if I would need to proceed the loop of existing windows? For example if I type I want to get handle of AOK window , but there is more windows and the AOK would not be the first window, but the third. So when I am in the callback, first handle is not what I search, but I cannot continue to the third call because it will stop on the end of first call.

  12. #117
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Capture of Window

    Don't you know F5 exists?
    Victor Nijegorodov

  13. #118
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    Quote Originally Posted by VictorN View Post
    Don't you know F5 exits?
    Ah so, I was pressing F10.

    Update #1:
    I have made improvement to the callback function. It will skip windows which are not top level on platforms prior to Windows 8.
    You can set minimum and maximum height of destination window.
    You can set your own style depending on your theme.
    These conditions saves processing of many program titles into for loop in versions prior Windows 8. In my case saved about 50 programs (but some of theme have no title, so may be irrelevant).

    Code:
    #define	CODE		81
    #define	WINDOW_MIN_HEIGHT		200
    #define	WINDOW_MAX_HEIGHT	700
    #define	WINSTYLE		0x14FF0000
    
    #include <windows.h>
    #include <cstdio>
    #include <fstream>
    #include <iostream>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    const int maxstr = 200;
    // const char wndtitle[] = "AOK";
    LONG t1; LONG t2;
    struct windata {
    	string partitle;
    	HWND hfnd; // Found destination window handler
    };
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    char *ch = title;
    RECT wrect;
    
    GetWindowRect(hwnd, &wrect);
    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;
    if (GetWindowTextA(hwnd, title, maxstr)) {
    		for (char *ch = title; *ch; ++ch) // was ch++)
    			*ch = (char)tolower(*ch);		
    		if (strstr(title, ((windata*)lparam)->partitle.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()
    {
    windata wd;
    	cout << "Partial window title: ";
    	getline(cin, wd.partitle);
    // ... rest of the code here
    }
    Notice that the struct does not contain integers initiation, but any string is assigned outside the struct class.
    Notice two difference operators are used to access the wd members of instance of struct/class windata.
    The difference in pointers is nicely described here
    dot operator: In the first form, postfix-expression represents a value of struct, class, or union type, and name names a member of the specified structure, union, or class. The value of the operation is that of name and is an l-value if postfix-expression is an l-value.
    arrow operator: In the second form, postfix-expression represents a pointer to a structure, union, or class, and name names a member of the specified structure, union, or class. The value is that of name and is an l-value. The –> operator dereferences the pointer. Therefore, the expressions e–>member and (*e).member (where e represents a pointer) yield identical results (except when the operators –> or * are overloaded).
    http://msdn.microsoft.com/en-us/libr...=vs.71%29.aspx

    Update #2:
    Here I add updated code. This will find one of four windows, starting on "learn", "dialog", "aok" or "map". Type lower case characters into window titles definition. If you open more than one window with the specified name, you can select what window should be selected otherwise you can press enter and default window will be selected.

    Code:
    #define	CODE		81
    #define	WINDOW_MIN_HEIGHT		200
    #define	WINDOW_MAX_HEIGHT	700
    #define	WINSTYLE		0x14FF0000
    
    #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;
    LONG t1; LONG t2;
    
    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";
    
    BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lparam)
    {
    char title[maxstr + 1];
    char *ch = title;
    RECT wrect;
    
    GetWindowTextA(hwnd, title, maxstr);
    
    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;
    
    if (GetWindowTextA(hwnd, title, maxstr)) {
    		for (char *ch = title; *ch; ++ch) // was ch++)
    			*ch = (char)tolower(*ch);		
    		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()
    {
    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;
    
    	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;
    	}

    #81 Separated codes; Target window responsive on WM_PRINTCLIENT. http://forums.codeguru.com/showthrea...05#post2154705

    Quote Originally Posted by 2kaud View Post
    Yes it was originally, but see my post #82 and #85. I moved away from any changes to the program producing the window to be captured. The code in #96 doesn't require any changes to the window producing program. The other program was simply a test program to produce a window containg an eclipse that could be captured This had a title of wintest - hence the use of wintest in the FindWindow().
    #82 http://forums.codeguru.com/showthrea...09#post2154709
    #85 http://forums.codeguru.com/showthrea...43#post2154743
    #96 http://forums.codeguru.com/showthrea...97#post2154797

    I need some time to check codes. Lots of work to do.
    Last edited by crazy boy; May 15th, 2014 at 06:07 AM.

  14. #119
    Join Date
    May 2014
    Posts
    205

    Re: Capture of Window

    Why am I getting error?

    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;
    
    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
    	const int fudgey = (GetMenu(HCapture)?GetSystemMetrics(SM_CYMENU):0) 
    					+ GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYSIZEFRAME);
    	const int 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);
    					*/
    					const int fudgey = (rectw.bottom - rectw.top) - dy - 2 * GetSystemMetrics(SM_CYSIZEFRAME);
    					const int 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;
    
    }
    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?

  15. #120
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Capture of Window

    Quote Originally Posted by crazy boy View Post
    Why am I getting error?

    ...
    '&' : check operator precedence for possible error; use parentheses to clarify precedence

    Something with rect, rectw declaration?
    It's telling you what the error is:
    "'&' : check operator precedence for possible error; use parentheses to clarify precedence"

    It's always tough to interpret the compiler errors at first. When I run across an compiler error I haven't seen before, I find it helpful to paste the error string into a bing or google search.

    You might consider adapting a more readable coding style that uses a bit of white space and better formatting. That way, these kinds of errors will jump right out at you.

    Another thing to do is if coding in Visual Studio, just double-click on the error and it usually will take you to the offending line of code.

Page 8 of 9 FirstFirst ... 56789 LastLast

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured