Создал окно и полосы прокрутки, а нужно добавить для полос прокрутки эффект прилипания. То есть при клике на полосу окно прилипает и перетаскивается, а при, например, двойном клике отлипает.
Знаю, что по WM_NCMOUSEMOVE захватывается ввод мыши SetCapture, а по WM_MOUSEMOVE двигается окно. Ну и с помощью WM_LBUTTONDBLCLK делаем RelaseCapture и окно перестает двигаться, но вот реализовать это не получается
Код:
#include <iostream>
#include <windows.h>
#define LINES 30
int global_x, global_y;
// Прототип для главной оконной процедуры
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
// Имя класса окна делается глобальной переменной
char g_szClassName[] = "MainWindow";
HWND FirstWindow; // Дескриптор окна
bool inWindow, top, bot, cancel = false;
int tenCounterUp = 50;
int tenCounterDown = 50;
int WINAPI WinMain(HINSTANCE ThisInstance
, HINSTANCE PreviousInstance
, LPSTR lpszArgument
, int CommandShow
) {
MSG Messages; // Здесь сохраняются все сообщения в приложении
WNDCLASS WindowClass; // Структура данных для пользовательского класса окна
WindowClass.hInstance = ThisInstance;
WindowClass.lpszClassName = g_szClassName;
// указатель на главную оконную процедуру
WindowClass.lpfnWndProc = WindowProcedure;
WindowClass.lpszMenuName = NULL; // Нет системного меню
// использование иконки по умолчанию
WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // курсор мыши - стрелка
// перерисовка всего окна при изменении высоты и ширины окна,
// а также перехват двойного клика
WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
// нет дополнительных байтов для класса окна
WindowClass.cbClsExtra = 0;
// нет дополнительных байтов для экземпляра окна
WindowClass.cbWndExtra = 0;
// для фона используется цвет по умолчанию
WindowClass.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
// зарегистрировать класс окна, а в случае ошибки завершить программу
// вычисление координат центра экрана
RECT screen_rect;
GetWindowRect(GetDesktopWindow(), &screen_rect); // разрешение экрана
int x = screen_rect.right / 2;
int y = screen_rect.bottom / 2;
if (0 == RegisterClass(&WindowClass))
return EXIT_FAILURE;
// создание окна
FirstWindow = CreateWindow(g_szClassName // Имя класса
, "Window" // заголовок окна
, WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL// перекрываемое окно
, CW_USEDEFAULT // ОС решает за нас,
, CW_USEDEFAULT // куда разместить окно
, x // ширина окна
, y // высота окна
, HWND_DESKTOP // это окно - потомок рабочего стола
, NULL // меню не выводится
, ThisInstance // дескриптор экземпляра программы
, NULL // без данных для создания окна
);
RECT Rect;
GetClientRect(FirstWindow, &Rect);
ShowWindow(FirstWindow, CommandShow);
UpdateWindow(FirstWindow);
// Цикл обработки сообщений
while (GetMessage(&Messages, NULL, 0, 0))
{
// трансляция сообщений виртуальных клавиш в символьные сообщения
TranslateMessage(&Messages);
// отправка сообщений в оконную процедуру
DispatchMessage(&Messages);
}
// Возвратить значение 0 из функции WinMain, которое она получит
// транзитивно от PostQuitMessage()
return Messages.wParam;
}
LRESULT CALLBACK WindowProcedure(HWND hWindow
, UINT uMessage
, WPARAM wFirstParameter
, LPARAM lSecondParameter
)
{
static int VscrollPos, HscrollPos;
int i;
PAINTSTRUCT ps;
char buffer[1024]; //размер буфера для текста
TEXTMETRIC tm;
switch (uMessage) // Обработка сообщений
{
case WM_CLOSE: // закрытие окна
DestroyWindow(hWindow);
return 0;
case WM_DESTROY: // удаление окна
PostQuitMessage(0); // отправка сообщения WM_QUIT в очередь сообщений
break;
case WM_NCLBUTTONDOWN: {
switch (wFirstParameter) {
case HTCAPTION:
EnableScrollBar(FirstWindow, SB_VERT, ESB_DISABLE_BOTH);
SendMessage(FirstWindow, WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);
break;
case HTVSCROLL: {
EnableScrollBar(FirstWindow, SB_VERT, ESB_ENABLE_BOTH);
return DefWindowProc(hWindow
, uMessage
, wFirstParameter
, lSecondParameter
);
}
default:
return DefWindowProc(hWindow
, uMessage
, wFirstParameter
, lSecondParameter
);
}
}
case WM_VSCROLL:
{
switch (LOWORD(wFirstParameter))
{
case SB_LINEUP:
break;
case SB_LINEDOWN:
break;
case SB_THUMBPOSITION:
VscrollPos = HIWORD(wFirstParameter);
break;
default:
break;
}
if (VscrollPos != GetScrollPos(FirstWindow, SB_VERT)) {
SetScrollPos(FirstWindow, SB_VERT, VscrollPos, TRUE);
InvalidateRect(FirstWindow, NULL, TRUE);
}
break;
}
case WM_HSCROLL:
{
switch (LOWORD(wFirstParameter))
{
case SB_LINEUP:
break;
case SB_LINEDOWN:
break;
case SB_THUMBPOSITION:
HscrollPos = HIWORD(wFirstParameter);
break;
default:
break;
}
if (HscrollPos != GetScrollPos(FirstWindow, SB_HORZ)) {
SetScrollPos(FirstWindow, SB_HORZ, HscrollPos, TRUE);
InvalidateRect(FirstWindow, NULL, TRUE);
}
break;
}
default: // Для сообщений, с которыми мы не хотим связываться
return DefWindowProc(hWindow
, uMessage
, wFirstParameter
, lSecondParameter
);
}
return 0;
}