I have a problem when I try hooking mouse events. It works if I click outside of my application window. But when I click inside my app window, it doesn't detect the WM_LBUTTONUP event. For few seconds mouse movement is very slow. And from this time it doesn't detect any events. Even if I click outside of my app window.
So my app runs indefinitely. I wonder if this is something related to threads or something. Maybe if I want to track something globally, in all threads in my computer (for example tracking mouse movement) then I can do nothing in my app thread? But this is very strange to me.
Here is code for mouse hooking. main.cpp
#include <windows.h>
#include <iostream>
#include "MyHook.h"
using namespace std;
int main()
{
    MyHook::Instance().InstallHook();
    return MyHook::Instance().Messsages();
}
MyHook.h
#pragma once
#include <Windows.h>
class MyHook
{
public:
    //single ton
    static MyHook& Instance()
    {
        static MyHook myHook;
        return myHook;
    }
    // function to install our mouseHook
    void InstallHook();
    // function to uninstall our mouseHook
    void UninstallHook();
    // function to "deal" with our messages
    int Messsages();
public:
    HHOOK mouseHook; // handle to the mouse hook
    HHOOK windowHook; // handle to the window hook
    MSG msg; // struct with information about all messages in our queue
};
LRESULT CALLBACK MyMouseCallback(int nCode, WPARAM wParam, LPARAM lParam);
MyHook.cpp
#include "MyHook.h"
#include <stdio.h>
void MyHook::InstallHook()
{
    /*
    SetWindowHookEx(
    WM_MOUSE_LL = mouse low level mouseHook type,
    MyMouseCallback = our callback function that will deal with system messages about mouse
    NULL, 0);
    c++ note: we can check the return SetWindowsHookEx like this because:
    If it return NULL, a NULL value is 0 and 0 is false.
    */
    if (!(mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MyMouseCallback, NULL, 0)))
    {
        printf_s("Error: %x \n", GetLastError());
    }
}
// function to uninstall our mouseHook
void MyHook::UninstallHook()
{
    UnhookWindowsHookEx(mouseHook);
}
MSG msg; // struct with information about all messages in our queue
// function to "deal" with our messages
int MyHook::Messsages()
{
    // while we do not close our application
    while (msg.message != WM_QUIT)
    {
        if (GetMessage(&msg, NULL, 0, 0/*, PM_REMOVE*/))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        Sleep(1);
    }
    UninstallHook(); // if we close, let's uninstall our mouseHook
    return (int)msg.wParam; // return the messages
}
LRESULT CALLBACK MyMouseCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    MSLLHOOKSTRUCT* pMouseStruct = (MSLLHOOKSTRUCT*)lParam; // WH_MOUSE_LL struct
    /*
    nCode, this parameters will determine how to process a message
    This callback in this case only have information when it is 0 (HC_ACTION): wParam and lParam contain info
    wParam is about WINDOWS MESSAGE, in this case MOUSE messages.
    lParam is information contained in the structure MSLLHOOKSTRUCT
    */
    // we have information in wParam/lParam ? If yes, let's check it:
    if (nCode == 0)
    { 
        // Mouse struct contain information?    
        // if (pMouseStruct != NULL)
        // {
        //  printf_s("Mouse Coordinates: x = %i | y = %i \n", pMouseStruct->pt.x, pMouseStruct->pt.y);
        // }
        switch (wParam)
        {
            case WM_LBUTTONDOWN:
            {
                printf_s("LEFT CLICK DOWN\n");
            }
            break;
            case WM_LBUTTONUP:
            {
                printf_s("LEFT CLICK UP\n");
            }
            break;
        }
    }
    /*
    Every time that the nCode is less than 0 we need to CallNextHookEx:
    -> Pass to the next mouseHook
         MSDN: Calling CallNextHookEx is optional, but it is highly recommended;
         otherwise, other applications that have installed hooks will not receive mouseHook notifications and may behave incorrectly as a result.
    */
    return CallNextHookEx(MyHook::Instance().mouseHook, nCode, wParam, lParam);
}