2012-05-20 2 views
1

어떤 제목을 사용해야할지 모르지만이 부분을 읽으십시오.WM_INPUT 및 GetPixel 관련 문제

마우스 포인터 위치에 색상을 표시하는 프로그램을 만들고 있습니다. WM_MOUSEMOVE가 충분히 빨리 업데이트되지 않기 때문에 WM_INPUT을 사용하고 싶습니다.

여기 내 주요 코드가 있습니다.

#include <Windows.h> 
#include <WindowsX.h> 

/* void Cls_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput) */ 
#define HANDLE_WM_INPUT(hWnd, wParam, lParam, fn) \ 
    ((fn)((hWnd), GET_RAWINPUT_CODE_WPARAM(wParam), (HRAWINPUT)(lParam)), 0L) 

static LPCTSTR main_window_class_name = TEXT("MainWindow"); 
static HDC hdc_screen; 
static COLORREF color; 

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 
BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct); 
void MainWindow_OnDestroy(HWND hWnd); 
void MainWindow_OnPaint(HWND hWnd); 
void MainWindow_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput); 

ATOM RegisterMainWindowClass(HINSTANCE hInstance) 
{ 
    WNDCLASSEX wcex; 

    wcex.cbSize = sizeof(wcex); 
    wcex.style = 0; 
    wcex.lpfnWndProc = MainWindowProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = hInstance; 
    wcex.hIcon = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED); 
    wcex.hCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); 
    wcex.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); 
    wcex.lpszMenuName = NULL; 
    wcex.lpszClassName = main_window_class_name; 
    wcex.hIconSm = wcex.hIcon; 

    return RegisterClassEx(&wcex); 
} 

HWND CreateMainWindow(HINSTANCE hInstance) 
{ 
    return CreateWindow(main_window_class_name, TEXT("WhatColor"), WS_CAPTION | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, HWND_DESKTOP, NULL, hInstance, NULL); 
} 

LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) 
    { 
    HANDLE_MSG(hWnd, WM_CREATE, MainWindow_OnCreate); 
    HANDLE_MSG(hWnd, WM_DESTROY, MainWindow_OnDestroy); 
    HANDLE_MSG(hWnd, WM_PAINT, MainWindow_OnPaint); 
    HANDLE_MSG(hWnd, WM_INPUT, MainWindow_OnInput); 
    default: 
    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
    } 
} 

BOOL MainWindow_OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) 
{ 
    RAWINPUTDEVICE rid[1]; 

    UNREFERENCED_PARAMETER(lpCreateStruct); 

    rid[0].usUsagePage = 1; 
    rid[0].usUsage = 2; 
    rid[0].dwFlags = 0; 
    rid[0].hwndTarget = hWnd; 
    RegisterRawInputDevices(rid, 1, sizeof(rid[0])); 

    hdc_screen = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); 

    return TRUE; 
} 

void MainWindow_OnDestroy(HWND hWnd) 
{ 
    UNREFERENCED_PARAMETER(hWnd); 

    DeleteDC(hdc_screen); 
    PostQuitMessage(EXIT_SUCCESS); 
} 

void MainWindow_OnPaint(HWND hWnd) 
{ 
    static PAINTSTRUCT ps; 

    BeginPaint(hWnd, &ps); 
    EndPaint(hWnd, &ps); 
} 

void MainWindow_OnInput(HWND hWnd, UINT inputCode, HRAWINPUT hRawInput) 
{ 
    static RAWINPUT raw_input; 
    static UINT raw_input_size = sizeof(raw_input); 
    static POINT point; 

    UNREFERENCED_PARAMETER(inputCode); 

    GetRawInputData(hRawInput, RID_HEADER, &raw_input, &raw_input_size, sizeof(raw_input.header)); 

    if (raw_input.header.dwType == RIM_TYPEMOUSE) 
    { 
    GetCursorPos(&point); 
    color = GetPixel(hdc_screen, point.x, point.y); 
    DeleteBrush(SetClassLong(hWnd, GCL_HBRBACKGROUND, (LONG)CreateSolidBrush(color))); 
    InvalidateRect(hWnd, NULL, TRUE); 
    } 
} 

문제는 프로그램이 WM_INPUT 메시지를 반복해서 처리하는 것으로 보이며 주 창이 멈췄습니다. 내가

color = GetPixel(hdc_screen, point.x, point.y); 

을 제거하면 윈도우가 정상이지만, 내가 원하는 색상을 얻을 수 없습니다.

내 코드를 테스트하려고하면 더 좋습니다.

이 문제를 해결하려면 어떻게해야합니까?

+1

당신은 당신이 요구 한 것을 가지고 있습니다, 당신은 지금 마우스 메시지의 소방 호스에서 마시고 있습니다. 처리 할 수있는 것보다 빨리 처리 할 수 ​​있지만 GetPixel()은 꽤 비쌉니다. GetRawInputBuffer()를 고려하십시오. OnInput에 버그가 있습니다. raw_input 대신 point를 사용합니다. –

+0

@HansPassant GetPixel()을 대체하는 데 사용할 수있는 다른 방법이 있습니까? – EFanZh

+0

잘못된 해결 방법을 찾고 있습니다. GetPixel()은 여전히 ​​사람의 눈보다 더 빠르게 전체를 체크합니다. –

답변

0

대신 타이머를 사용하고 WM_TIMER 메시지를 처리합니다.