4

I am having trouble thinking of a way of creating a program that monitors anytime the clipboard is used and have it print out in a .txt file (It should be bale to monitor the clipboard for any window/application). I used the Using the Clipboard WIn32, but I am not sure how I can have this process constantly running? I am able to get the clipboard once but my program stops. Should I use a while loop? Basically, my program only runs once when I want it to keep tracking the changes. What should I do?

///

Would Clipboard Format Listener help with what I need?

///

int main()
{
    OpenClipboard(nullptr);
    HANDLE hData = GetClipboardData(CF_TEXT);
    char* pszText = static_cast<char*>(GlobalLock(hData));
    string text = pszText;
    GlobalUnlock(hData);
    CloseClipboard();

    cout << text;
    return 0;
}
dxiv
  • 16,984
  • 2
  • 27
  • 49
Juansdk
  • 93
  • 5
  • 2
    Things like "clipboard" are very operating system dependent, and sometimes even environment dependent. Please [edit] your question to include at least your target operating system as a tag. Also please take some time to read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Jan 22 '21 at 06:30
  • @Someprogrammerdude please look above. Changed. – Juansdk Jan 22 '21 at 06:42
  • 2
    Maybe investigate using the [WM_CLIPBOARDUPDATE](https://learn.microsoft.com/en-us/windows/win32/dataxchg/wm-clipboardupdate) message. There may even be another post somewhere on Stack Overflow... – Adrian Mole Jan 22 '21 at 08:22
  • 2
    ... maybe not exactly a duplicate, but here: https://stackoverflow.com/q/59460658/10871073 – Adrian Mole Jan 22 '21 at 08:23
  • Already looked that these resources. Still quite confused. – Juansdk Jan 22 '21 at 08:39

1 Answers1

2

Subscribing to the WM_CLIPBOARDUPDATE message using AddClipboardFormatListener requires a message queue and a message pump. For a console app, this can be done with a message-only window and a corresponding message loop. Below is some barebones code to implement both.

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

LRESULT CALLBACK ClipWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static BOOL bListening = FALSE;
    switch(uMsg)
    {
    case WM_CREATE:
        bListening = AddClipboardFormatListener(hWnd);
        return bListening ? 0 : -1;

    case WM_DESTROY:
        if(bListening)
        {
            RemoveClipboardFormatListener(hWnd);
            bListening = FALSE;
        }
        return 0;

    case WM_CLIPBOARDUPDATE:
        printf("WM_CLIPBOARDUPDATE\n");
        return 0;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}


int main()
{
    WNDCLASSEX wndClass = { sizeof(WNDCLASSEX) };
    wndClass.lpfnWndProc = ClipWndProc;
    wndClass.lpszClassName = L"ClipWnd";
    if(!RegisterClassEx(&wndClass))
    {   printf("RegisterClassEx error 0x%08X\n", GetLastError()); return 1; }
    HWND hWnd = CreateWindowEx(0, wndClass.lpszClassName, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
    if(!hWnd)
    {   printf("CreateWindowEx error 0x%08X\n", GetLastError()); return 2; }

    printf("Press ^C to exit\n\n");

    MSG msg;
    while(BOOL bRet = GetMessage(&msg, 0, 0, 0)) {
        if(bRet == -1)
        {   printf("GetMessage error 0x%08X\n", GetLastError()); return 3; }
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}
dxiv
  • 16,984
  • 2
  • 27
  • 49