susam / uncap

Map Caps Lock to Escape or any key to any key
MIT License
1.08k stars 44 forks source link

Windows 10: Output window is displayed #6

Closed peterjuras closed 5 years ago

peterjuras commented 6 years ago

Hi!

Thanks for creating this utility! Sadly it appears that whenever I am running Uncap, an Output window appears as seen in this screenshot. Do you know what could be the issue?

Windows Version: Windows 10 Pro | 1709 | 16299.402 Uncap Version: 0.2.2

navhaxs commented 6 years ago

I just came across this issue today. It appears to be due to 'ConEmu' running on the system when starting uncap. I might have a look at the source, could be an easy fix.

susam commented 5 years ago

Thank you, Peter (@peterjuras), for reporting this issue.

Thank you, Jeremy (@navhaxs), for creating pull request #7 to resolve this.

As I have explained in the pull request page, the root cause of the issue here is that in the presence of Cmder, the FindWindow("ConsoleWindowClass", NULL) call gets a handle to another window (not the window in which Uncap is running), so the ShowWindow(h, SW_HIDE) call later attempts to hide the wrong window.

For now, I have merged this pull request #7 as is, so that it remains in the commit history of this project. Your pull request resolves the issue by working around the issue with the FreeConsole() call that detaches Uncap from the console regardless of which handle we got with the FindWindow() call.

I will be pushing another commit soon that addresses the root cause of the issue.

Update: I have pushed commit 0bbf27e92e5fb5bc9991c6cad24e5b78d72e8140 that addresses the root cause of the issue. See next comment for more details on the root cause of the issue.

susam commented 5 years ago

Root Cause Demonstration Code

As I mentioned in my previous comment, the root cause of the issue is that the FindWindow("ConsoleWindowClass", NULL) call gets a handle to another window, not the one in which Uncap is running.

Here is an example code that demonstrates the root cause of the issue:

#include <stdio.h>
#include <windows.h>

void printWindowDetails(HWND h)
{
    char buffer[256];
    WINDOWINFO info;
    int ret;

    if (h == NULL) {
        printf("  - window handle is NULL; error %lu\n", GetLastError());
    }

    ret = GetWindowText(h, buffer, 255);
    if (ret > 0) {
        printf("  - window text: %s\n", buffer);
    } else {
        printf("  - cannot get window text; error %lu\n", GetLastError());
    }

    ret = GetWindowModuleFileName(h, buffer, 255);
    if (ret > 0) {
        printf("  - window module file name: %s\n", buffer);
    } else {
        printf("  - cannot get window text; error %lu\n", GetLastError());
    }

    info.cbSize = sizeof info;
    ret = GetWindowInfo(h, &info);
    if (ret) {
        RECT rect;

        rect = info.rcWindow;
        printf("  - window coordinates: (%ld, %ld), (%ld, %ld)\n",
               rect.top, rect.left, rect.bottom, rect.right);

        rect = info.rcClient;
        printf("  - client coordinates: (%ld, %ld), (%ld, %ld)\n",
               rect.top, rect.left, rect.bottom, rect.right);

        printf("  - window status: %d\n", info.dwWindowStatus);
    } else {
        printf("  - cannot get window info; error %lu\n", GetLastError());
    }

    printf("\n");
}

int main()
{
    HWND h;

    printf("FindWindow(\"ConsoleWindowClass\", NULL):\n");
    h = FindWindow("ConsoleWindowClass", NULL);
    printWindowDetails(h);

    printf("GetConsoleWindow():\n");
    h = GetConsoleWindow();
    printWindowDetails(h);

    printf("press ENTER to exit\n");
    getchar();

    return 0;
}

This code can be compiled with GCC (MinGW) as follows:

gcc -std=c89 -Wall -Wextra -Wpedantic foo.c -o foo

Cmder Not Running

Here is the output when this program is run by double-clicking when Cmder is not running:

FindWindow("ConsoleWindowClass", NULL):
  - window text: C:\Users\susam\Downloads\uncap\foo.exe
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (130, 130), (649, 1123)
  - client coordinates: (161, 138), (641, 1098)
  - window status: 1

GetConsoleWindow():
  - window text: C:\Users\susam\Downloads\uncap\foo.exe
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (130, 130), (649, 1123)
  - client coordinates: (161, 138), (641, 1098)
  - window status: 1

press ENTER to exit

We can see above that both FindWindow() and GetConsoleWindow() return the same window as expected.

Cmder Launching

Here is the output when Cmder is launching:

FindWindow("ConsoleWindowClass", NULL):
  - window text: cmd - "C:\Users\susam\Downloads\cmder_mini\vendor\conemu-maximus5\..\init.bat"
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (0, 0), (189, 393)
  - client coordinates: (31, 8), (181, 368)
  - window status: 0

GetConsoleWindow():
  - window text: C:\Users\susam\Downloads\uncap\foo.exe
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (130, 130), (649, 1123)
  - client coordinates: (161, 138), (641, 1098)
  - window status: 1

press ENTER to exit

We can see that FindWindow() returns a different window in which Cmder initialization script is running. This is the issue.

Cmder Launched

Here is the output when Cmder has launched:

FindWindow("ConsoleWindowClass", NULL):
  - window text: Administrator: cmd
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (0, 0), (189, 393)
  - client coordinates: (31, 8), (181, 368)
  - window status: 0

GetConsoleWindow():
  - window text: C:\Users\susam\Downloads\uncap\foo.exe
  - window module file name: C:\Users\susam\Downloads\uncap\foo.exe
  - window coordinates: (130, 130), (649, 1123)
  - client coordinates: (161, 138), (641, 1098)
  - window status: 1

press ENTER to exit

We can see that FindWindow() returns a different window.

Fix

The correct fix this to issue is to use GetConsoleWindow() instead of FindWindow() to get the handle to the current window. Commit 0bbf27e92e5fb5bc9991c6cad24e5b78d72e8140 implements this fix. I will later release a new version of Uncap that contains this fix and then close this issue.

susam commented 5 years ago

The fix for this issue is now available in Uncap 0.3.0.

Closing this issue now.