Неправильная точка доступа для курсора I-Beam в Windows 7? - PullRequest
4 голосов
/ 28 апреля 2011

Проблема

В окнах координаты, возвращаемые для события «кнопка мыши вниз», кажутся немного неправильными для курсора I-Beam. По сути, координата x всегда находится в двух пикселях от того места, где она должна быть.

Я написал очень простую программу для win32, чтобы продемонстрировать проблему. Все, что он делает, это превращает курсор в IBeam и визуализирует вертикальную красную линию, где было последнее событие нажатия мыши. Я ожидаю, что красная линия точно совпадет с вертикальной частью двутавровой балки, но это не так.

Вот скриншот того, что происходит .

Как видите, красная линия находится в двух пикселях слева от того места, где она должна быть (поведение для стандартного указателя стрелки правильное), поэтому создается впечатление, что точка доступа для курсора I-Beam неверна.

У меня есть кто-то еще, работающий под управлением Windows 7 64-битный, подтвердите, что они сталкиваются с той же проблемой, но другой тестер на Vista не имеет проблемы.


Некоторая информация о моем окружении

  • Windows 7 64 бит. Конфигурация полностью по умолчанию (т.е. без масштабирования DPI, без странных тем и т. Д.)
  • Visual Studio Express 2010
  • Видеокарта NVidia с последними драйверами (v270.61)
  • Включение или выключение Aero не имеет значения. Выбор разных курсоров в настройках дисплея не имеет значения

Соответствующие биты кода

Мой тестовый проект - это в основном шаблон Win32 Project в Visual C ++ 2010 с изменениями, описанными ниже.

Вот код, где я регистрирую класс окна и устанавливаю курсор на I Beam

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CURSOR_TEST));
    wcex.hCursor        = LoadCursor(NULL, IDC_IBEAM); // this is the only line I changed in this function
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_CURSOR_TEST);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

Вот соответствующие части из моего основного цикла сообщений:

case WM_LBUTTONDOWN:
    // record position of mouse down. 
    // xPos and yPos are just declared as
    // global ints for the purpose of this test
    xPos = GET_X_LPARAM(lParam); 
    yPos = GET_Y_LPARAM(lParam);
    // cause redraw
    InvalidateRect(hWnd, NULL, TRUE);
    UpdateWindow(hWnd);
    break;      

case WM_PAINT:
    // paint vertical red line at position of last click
    hdc = BeginPaint(hWnd, &ps);
    RECT rcClient;
    GetClientRect(hWnd, &rcClient);
    hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
    SelectObject(hdc, hPen);
    MoveToEx(hdc, xPos, 0, NULL);
    LineTo(hdc, xPos, rcClient.bottom);
    DeleteObject(hPen);
    EndPaint(hWnd, &ps);
    break;

Резюме

Я много гуглил для ответов, но не могу найти что-нибудь подходящее. Я делаю что-то не так с обработкой входящих координат курсора?

Спасибо!


РЕДАКТИРОВАТЬ: дополнительная информация после проницательных вопросов в комментариях

Руководствуясь @Mark Ransom в комментариях, я использовал функцию GetIconInfo, чтобы получить больше информации о курсоре I-Beam. Структура ICONINFO для курсора указывает, что координата x для горячей точки курсора равна x = 8. Однако, когда я выгружаю растровое изображение для курсора (элемент hbmMask структуры ICONINFO, так как это монохромный курсор), вертикальная полоса находится в 10 пикселях слева от изображения, а не в 8 пикселях. Как указывает Марк, это, вероятно, является причиной визуальной несоответствия, но почему это произошло и как я могу это исправить?

(я также заметил, что ответ на этот другой вопрос содержит некоторую интересную информацию о том, как обрабатываются курсоры I-Beam. Интересно, уместно ли это)

...