Ответ 1
Я взял SDL2 и провел последние несколько часов, экспериментируя с различными API-интерфейсами для перемещения/масштабирования/перерисовки окна:
SDL_SetWindowPosition(window, newWindowPos.x, newWindowPos.y);
SDL_SetWindowSize(window, newWindowSize.x, newWindowSize.y);
SetWindowPos(windowHandle, nullptr, newWindowPos.x, newWindowPos.y, newWindowSize.x, newWindowSize.y, SWP_SHOWWINDOW);
MoveWindow(windowHandle, newWindowPos.x, newWindowPos.y, newWindowSize.x, newWindowSize.y, TRUE);
и
MoveWindow(windowHandle, newWindowPos.x, newWindowPos.y, newWindowSize.x, newWindowSize.y, TRUE);
InvalidateRect(windowHandle, &windowRect, TRUE);
Я узнал, что API-интерфейсы SDL хорошо справляются с медленными, небольшими перетаскиваниями, но большие, более быстрые перетаскивания запускают визуальный глюк, который вы описываете.
SetWindowPos
и MoveWindow
кажутся почти идентичны - оба работают правильно в моей системе. При перетаскивании на левом краю окна происходит сбой, но это согласуется с поведением других окон в моей системе. Правый край остается визуально фиксированным на месте без скрещивания. Вероятно, я бы выбрал вызов MoveWindow
для постоянного решения, хотя это в основном чувство кишки, основанное на том, как запускались различные настройки API. YMMV.
InvalidateRect
, похоже, не имеет никакого отношения к тому, как делаются вещи. Это не усугубляет левый пограничный глюк, о котором я упоминал, и не смягчает его. Я предполагаю, что это потому, что я указал флаг перерисовки для вызова MoveWindow
.
Для справки, здесь код, который я использовал для тестирования. Я просто прокомментировал/раскомментировал соответствующие API-интерфейсы и при необходимости восстановил проект. Извините за беспорядок - я больше интересовался тем, что делал что-то и работал, чем улучшал код. Дайте мне знать, если вы хотите, чтобы я немного почистил его.
//Using SDL and standard IO
#include <windows.h>
#include <SDL.h>
#include <SDL_syswm.h>
#include <stdio.h>
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
struct Point
{
int x;
int y;
};
int main(int argc, char* args[])
{
bool quit = false, dragging = false;
//The window we'll be rendering to
SDL_Window* window = NULL;
//The surface contained by the window
SDL_Surface* screenSurface = NULL;
SDL_Event e;
SDL_SysWMinfo windowInfo;
HWND windowHandle;
Point mousePos, windowPos, newWindowPos, newWindowSize, mWindowResizeOffset;
//Initialize SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
//Create window
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS); // | SDL_WINDOW_RESIZABLE
if(window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
//Get window surface
screenSurface = SDL_GetWindowSurface(window);
SDL_VERSION(&windowInfo.version);
SDL_GetWindowWMInfo(window, &windowInfo);
windowHandle = windowInfo.info.win.window;
//While application is running
while(!quit)
{
//Handle events on queue
while(SDL_PollEvent(&e) != 0)
{
//process events
switch(e.type)
{
case SDL_QUIT:
quit = true;
break;
case SDL_WINDOWEVENT:
if(e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
{
screenSurface = SDL_GetWindowSurface(window);
}
//Fill the surface blue
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x00, 0xA2, 0xE8));
//Update the surface
SDL_UpdateWindowSurface(window);
break;
case SDL_MOUSEBUTTONDOWN:
SDL_GetMouseState(&mWindowResizeOffset.x, &mWindowResizeOffset.y);
SDL_GetWindowPosition(window, &windowPos.x, &windowPos.y);
dragging = true;
break;
case SDL_MOUSEBUTTONUP:
dragging = false;
break;
case SDL_MOUSEMOTION:
if(dragging)
{
SDL_GetMouseState(&mousePos.x, &mousePos.y);
SDL_GetWindowPosition(window, &newWindowPos.x, &newWindowPos.y);
SDL_GetWindowSize(window, &newWindowSize.x, &newWindowSize.y);
newWindowPos.x = newWindowPos.x + mousePos.x - mWindowResizeOffset.x;
newWindowSize.x += windowPos.x - newWindowPos.x;
//SDL_SetWindowPosition(window, newWindowPos.x, newWindowPos.y);
//SDL_SetWindowSize(window, newWindowSize.x, newWindowSize.y);
//SetWindowPos(windowHandle, nullptr, newWindowPos.x, newWindowPos.y, newWindowSize.x, newWindowSize.y, SWP_SHOWWINDOW);
MoveWindow(windowHandle, newWindowPos.x, newWindowPos.y, newWindowSize.x, newWindowSize.y, TRUE);
/*RECT drawRect;
drawRect.left = windowPos.x;
drawRect.top = windowPos.y;
drawRect.right = windowPos.x + newWindowSize.x;
drawRect.bottom = windowPos.y + newWindowSize.y;
InvalidateRect(windowHandle, &drawRect, TRUE);*/
windowPos = newWindowPos;
}
break;
}
}
SDL_Delay(1);
}
}
}
//Destroy window
SDL_DestroyWindow(window);
//Quit SDL subsystems
SDL_Quit();
return 0;
}