Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

c++ - I am trying to check if the specified window is visible to the screen using Winapi but not sure how to approach when two windows are not overlapped

What I am trying to do is combining the regions of the top windows and checking if the specified window is present in the region if it is then displaying result. It does not giving results very accurately. And also I have problem when windows are non-overlapped. Does any one have any idea how to overcome this situation. p is the foreground process

while (p != NULL)
{
    if (IsWindowVisible(p)) {
        if ((GetWindowLongPtr(p, GWL_STYLE) & WS_ICONIC) || GetWindowLong(p, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) {
        }
        else
        {
            RECT a;

            if (GetWindowText(p, str, 255)) {

                if ((_wcsicmp(str, _T("Program Manager"))))
                {

                    GetWindowThreadProcessId(p, &proc_id);
                    proc_hnd = OpenProcess(PROCESS_ALL_ACCESS, TRUE, proc_id);
                    flag = GetProcessImageFileName(proc_hnd, proc_name, 1024);
                    wstring test(&proc_name[0]); //convert to wstring
                    string test2(test.begin(), test.end());
                    LOGGER->info(test2);
                    GetWindowRect(p, &a);

                    z = CreateRectRgn(a.left, a.top, a.right, a.bottom);
                    if (wcsstr(proc_name, L"chrome.exe")) {
                        RECT op;
                        GetWindowRect(p, &op);
                        HRGN j1 = CreateRectRgn(op.left, op.top, op.right, op.bottom);

                        CombineRgn(j1, j1, y, RGN_DIFF); emphasized text
                            CombineRgn(y, y, z, RGN_OR);    //combining the region
                        switch (GetRgnBox(j1, &a))
                        {
                        case NULLREGION:

                            LOGGER->info("null region");
                            break;
                        case SIMPLEREGION:
                            LOGGER->info("simple region");
                            break;
                        case COMPLEXREGION:
                            LOGGER->info("complex region");
                            break;
                        default:
                            LOGGER->info("default region");

                        }

                    }
                    else
                    {
                        CombineRgn(y, y, z, RGN_OR);  //combining the region
                    }

                }
            }
        }
    }
    p = GetWindow(p, GW_HWNDNEXT); //getting the next window
}
question from:https://stackoverflow.com/questions/65857191/i-am-trying-to-check-if-the-specified-window-is-visible-to-the-screen-using-wina

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I use the IsOverlapped sample here, but it is used to detect whether it is overlapped by any window. I modified this sample to check whether the window is visible:

BOOL IsVisible(HWND window)
{
    HWND hWnd = window;
    RECT thisRect;
    if (!IsWindowVisible(window))
        return FALSE;

    GetWindowRect(window, &thisRect);
    HWND explorer = FindWindow(L"Shell_TrayWnd", NULL);
    DWORD explorer_pid;
    GetWindowThreadProcessId(explorer, &explorer_pid);

    HRGN hrgn_above = CreateRectRgn(0, 0, 0, 0);
    HRGN hrgn_window = CreateRectRgnIndirect(&thisRect);
    while ((hWnd = GetWindow(hWnd, GW_HWNDPREV)) != NULL)
    {
        DWORD pid;
        GetWindowThreadProcessId(hWnd, &pid);
        if (pid == explorer_pid || !IsWindowVisible(hWnd))
            continue;
        RECT rc = {};
        GetWindowRect(hWnd, &rc);
        HRGN hrgn_hWnd = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
        CombineRgn(hrgn_above, hrgn_above, hrgn_hWnd, RGN_OR);
        DeleteObject(hrgn_hWnd);
    }
    int ret = CombineRgn(hrgn_window, hrgn_window, hrgn_above, RGN_DIFF);
    DeleteObject(hrgn_above);
    DeleteObject(hrgn_window);
    if (ret != NULLREGION && ret)
        return TRUE;
    
    return FALSE;
}

Use GetWindow + GW_HWNDPREV to get the windows list above the hWnd in Z order.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...