iamwho Posted May 4 Posted May 4 #include <Windows.h> #include <iostream> #include <windowsx.h> #define IDB_EXIT 102 PAINTSTRUCT ps; HDC hdc; RECT starfield_rc; BOOL g_bDragging = FALSE; POINT g_ptDragStart; int WIDTH = 350; int HEIGHT = 400; const int numStars = 50; const int starSpeed = 1; struct Star { int x, y; int speed; }; const int NUM_STARS = 100; Star stars[NUM_STARS]; HDC hdcMem; HBITMAP hbmMem; HBITMAP hbmOld; void starfield(HDC hdc, int x, int y, RECT *rc) { int width = 335; rc->left = x; rc->top = y; rc->right = width; rc->bottom = 249; HDC hdcMem = CreateCompatibleDC(hdc); HBITMAP hbmMem = CreateCompatibleBitmap(hdc, width, 215); HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbmMem); HBRUSH brush = CreateSolidBrush(RGB(0, 0, 0)); FillRect(hdcMem, rc, brush); DeleteObject(brush); for (int i = 0; i < NUM_STARS; i++) { SetPixel(hdcMem, stars[i].x, stars[i].y, RGB(255, 255, 255)); stars[i].x = (stars[i].x + stars[i].speed) % width; } BitBlt(hdc, x, y, width, 215, hdcMem, 0, 0, SRCCOPY); SelectObject(hdcMem, hbmOld); DeleteObject(hbmMem); DeleteDC(hdcMem); } // main function LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lparam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int nCmdShow) { for (int i = 0; i < NUM_STARS; i++) { stars[i].x = rand() % 340; stars[i].y = rand() % 249; stars[i].speed = rand() % 3 + 1; } TCHAR appname[] = TEXT("Template"); WNDCLASS wndclass; MSG msg; HWND hwnd; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hInstance = hInstance; wndclass.lpfnWndProc = WndProc; wndclass.lpszClassName = appname; wndclass.lpszMenuName = NULL; wndclass.style = CS_HREDRAW | CS_VREDRAW; // check this window class is registered or not if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("Window class is not registered"), TEXT("Error...."), MB_ICONERROR); return 0; } hwnd = CreateWindowEx(0, appname, // window name appname, // window text WS_VISIBLE | WS_POPUP, // set POPUP window style for no border & controls 100, // window position x 100, // window position y WIDTH, // width HEIGHT, // height NULL, NULL, hInstance, NULL); // show & update created window SetTimer(hwnd, 1, 10, NULL); // Set a timer to trigger every 100ms ShowWindow(hwnd, nCmdShow); // get message from queue while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } bool isSizingOrMoving = false; // WndProc function LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HINSTANCE hIns; HWND exit_button, gen_button, title, license; LRESULT move = NULL; static int xClick; static int yClick; switch (message) { case WM_CREATE: { exit_button = CreateWindow(TEXT("BUTTON"), NULL, WS_CHILD | WS_VISIBLE | BS_BITMAP, 250, 360, 70, 30, hwnd, (HMENU)100, hIns, 0); HBITMAP exitImg = (HBITMAP)LoadImageA(GetModuleHandleA(nullptr), (LPCSTR)MAKEINTRESOURCE(IDB_EXIT), IMAGE_BITMAP, 0, 0, NULL); title = CreateWindow(TEXT("STATIC"), TEXT("Hello"), WS_CHILD | WS_VISIBLE, 150, 5, 120, 20, hwnd, 0, hIns, 0); SendMessageW(exit_button, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)exitImg); } break; case WM_PAINT: { PAINTSTRUCT ps; hdc = BeginPaint(hwnd, &ps); starfield(hdc, 6, 31, &starfield_rc); EndPaint(hwnd, &ps); break; } case WM_TIMER: InvalidateRect(hwnd, &starfield_rc, FALSE); break; case WM_COMMAND: switch (wParam) { case 100: PostQuitMessage(EXIT_SUCCESS); return 0; } break; case WM_CTLCOLORSTATIC: { hdc = (HDC)wParam; return (LRESULT)CreateSolidBrush(RGB(0, 0, 0)); // black and white break; } case WM_CTLCOLOREDIT: { hdc = (HDC)wParam; return (LRESULT)CreateSolidBrush(RGB(0, 0, 0)); // black and white break; } case WM_LBUTTONDOWN: { // Start dragging g_bDragging = TRUE; g_ptDragStart.x = LOWORD(lParam); g_ptDragStart.y = HIWORD(lParam); SetCapture(hwnd); } return 0; case WM_MOUSEMOVE: { if (g_bDragging) { // Calculate the offset int dx = LOWORD(lParam) - g_ptDragStart.x; int dy = HIWORD(lParam) - g_ptDragStart.y; // Get the current window position RECT rc; GetWindowRect(hwnd, &rc); // Move the window by the offset SetWindowPos(hwnd, NULL, rc.left + dx, rc.top + dy, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } return 0; case WM_LBUTTONUP: { // Stop dragging g_bDragging = FALSE; ReleaseCapture(); } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } This is my starfield animation. Although you can drag the window. But if you drag it from extreme left or the top area, it gets lost. Can anyone help on how to fix this? 2
Kurapica Posted May 4 Posted May 4 What exactly gets lost ? Can you attach images before and after moving the window ? https://stackoverflow.com/questions/7773771/how-do-i-implement-dragging-a-window-using-its-client-area 1
iamwho Posted May 4 Author Posted May 4 40 minutes ago, Kurapica said: What exactly gets lost ? When you drag it fastly from the title, it gets lost. 1
adoxa Posted May 5 Posted May 5 LOWORD & HIWORD are unsigned, so when the mouse moves outside the window you're getting big values, causing it to go offscreen; use GET_X_LPARAM & GET_Y_LPARAM instead, then it will work fine. 1
TeRcO Posted 13 hours ago Posted 13 hours ago "Local variables (hdcMem, hbmMem, hbmOld) in the starfield() function conflict with global ones. The window size (WIDTH = 350, HEIGHT = 400) doesn’t match the starfield size (335 width and 249 height). Make them consistent if intended. Ensure that IDB_EXIT is properly defined in your resources (e.g., .rc file). If not, the LoadImageA call will fail. In WM_MOUSEMOVE, SetWindowPos is called every time the mouse moves, which may cause performance issues. " 1
fearless Posted 12 hours ago Posted 12 hours ago (edited) I would just use case WM_NCHITTEST and in that event check for g_bDragging is true, if so then use SendMessage with WM_NCLBUTTONDOWN and HTCAPTION, that way you will drag the entire window as if it had a caption/titlebar whenever mouse is down. So I would remove the WM_MOUSEMOVE and add something like this: case WM_NCHITTEST: { if (g_bDragging) { SendMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); } } return 0; Edited 12 hours ago by fearless 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now