无边框窗体缩放时抖动

PG_12138 2017-11-11 01:02:45
刚接触win32, 写了一个简单的无边框窗体。但当在窗体左上角对窗体进行缩放时,窗体的右边界和下边界会不断抖动。在右上角和左下角缩放时有相同的问题。在右下角缩放时是正常的。请问怎么解决?
代码如下
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif

#include <tchar.h>
#include <windows.h>

/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/* Make the class name into a global variable */
TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp");

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */

/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);

/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_GRAYTEXT;

/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;

/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
_T("Code::Blocks Template Windows App"), /* Title Text */
WS_POPUP, /* default window */
200, /* Windows decides the position */
200, /* where the window ends up on the screen */
640, /* The programs width */
480, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);

/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);

/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}

/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}


/* This function is called by the Windows function DispatchMessage() */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT pt;
RECT rcClient;

switch (message) /* handle the messages */
{

case WM_NCHITTEST:

pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
ScreenToClient(hwnd,&pt);
GetClientRect(hwnd, &rcClient);

if (pt.x<rcClient.left+5&&pt.y<rcClient.top+5)//×óÉϽÇ
{
return HTTOPLEFT;
}
if (pt.x>rcClient.right-5 && pt.y<rcClient.top+5)//ÓÒÉϽÇ
{
return HTTOPRIGHT;
}
if (pt.x<rcClient.left+5 && pt.y>rcClient.bottom-5)//×óϽÇ
{
return HTBOTTOMLEFT;
}
if (pt.x>rcClient.right-5 && pt.y>rcClient.bottom-5)//ÓÒϽÇ
{
return HTBOTTOMRIGHT;
}
if (pt.y<rcClient.top+10)
{
return HTCAPTION;
}
break;

case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}

return 0;
}
...全文
268 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2017-11-12
  • 打赏
  • 举报
回复
給你改了改,(WM_NCHITTEST), 没问题的 ,4个角 缩放 ,客户区移动。

// w32NoBoard.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#include <windows.h> 
#include <tchar.h> 
#include <stdio.h> 
  
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("WindowsApp"); 
  
int WINAPI WinMain (HINSTANCE hThisInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR lpszArgument, 
                     int nCmdShow) 
{ 
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
  
    /* The Window structure */
    wincl.cbSize = sizeof (WNDCLASSEX); 
    wincl.hInstance = hThisInstance; 
    wincl.lpszClassName = szClassName; 
    wincl.lpfnWndProc = WindowProcedure;/* This function is called by windows */
    wincl.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;/* Catch double-clicks */
  
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
    wincl.lpszMenuName = NULL;  /* No menu */
    wincl.cbClsExtra = 0;       /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;       /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) CTLCOLOR_DLG;//COLOR_GRAYTEXT; 
  
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl)) return 0; 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx(0, /* Extended possibilites for variation */
           szClassName,      /* Classname */
           0,				 /* Title Text */
           WS_POPUP, /* default window */
           200,      /* Windows decides the position */
           200,      /* where the window ends up on the screen */
           640,          /* The programs width */
           480,          /* and height in pixels */
           HWND_DESKTOP, /* The window is a child-window to desktop */
           NULL,         /* No menu */
           hThisInstance,/* Program Instance handler */
           NULL          /* No Window Creation data */
           ); 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0)) 
    {/* Translate virtual-key messages into character messages */
        TranslateMessage(&messages); 
        /* Send message to WindowProcedure */
        DispatchMessage(&messages); 
    } 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam; 
} 
//  
#define TestBorder 5

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
static POINT ptLast;
    POINT pt; 
    RECT rc;
    switch (message)
    { 
        case WM_NCHITTEST: 
			pt.x = LOWORD(lParam); 
			pt.y = HIWORD(lParam); 
			GetWindowRect(hwnd, &rc); 
 // move window
			rc.top+=TestBorder;
			rc.bottom-=TestBorder;
			rc.left+=TestBorder;
			rc.right-=TestBorder;
			if(PtInRect(&rc,pt))
			{
				return HTCAPTION; 
			}
// size window
			if (pt.x < rc.left && pt.y < rc.top)
			{ 
				return HTTOPLEFT; 
			} 
			if (pt.x>rc.right && pt.y<rc.top)
			{ 
				return HTTOPRIGHT; 
			} 
			if (pt.x<rc.left && pt.y>rc.bottom)
			{ 
				return HTBOTTOMLEFT; 
			} 
			if (pt.x>rc.right && pt.y>rc.bottom)
			{ 
				return HTBOTTOMRIGHT; 
			} 
			break; 
        case WM_CHAR:
			if((TCHAR) wParam == VK_RETURN) PostQuitMessage (0);       
            break; 
		case WM_MOUSEMOVE:
			pt.x = LOWORD(lParam);
			pt.y = HIWORD(lParam);  
			if(MK_LBUTTON==wParam)
			{
				GetWindowRect(hwnd,&rc);
				::MoveWindow(hwnd,rc.left+(pt.x-ptLast.x), rc.top+(pt.y-ptLast.y),
					rc.right-rc.left, rc.bottom-rc.top,TRUE);
			}
			else
			{
				ptLast=pt;
			}
		break;
        default: /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam); 
    } 
//  
    return 0; 
} 

PG_12138 2017-11-12
  • 打赏
  • 举报
回复
引用 4 楼 schlafenhamster 的回复:
給你改了改,(WM_NCHITTEST), 没问题的 ,4个角 缩放 ,客户区移动。

// w32NoBoard.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#include <windows.h> 
#include <tchar.h> 
#include <stdio.h> 
  
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("WindowsApp"); 
  
int WINAPI WinMain (HINSTANCE hThisInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR lpszArgument, 
                     int nCmdShow) 
{ 
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
  
    /* The Window structure */
    wincl.cbSize = sizeof (WNDCLASSEX); 
    wincl.hInstance = hThisInstance; 
    wincl.lpszClassName = szClassName; 
    wincl.lpfnWndProc = WindowProcedure;/* This function is called by windows */
    wincl.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;/* Catch double-clicks */
  
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); 
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW); 
    wincl.lpszMenuName = NULL;  /* No menu */
    wincl.cbClsExtra = 0;       /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;       /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) CTLCOLOR_DLG;//COLOR_GRAYTEXT; 
  
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl)) return 0; 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx(0, /* Extended possibilites for variation */
           szClassName,      /* Classname */
           0,				 /* Title Text */
           WS_POPUP, /* default window */
           200,      /* Windows decides the position */
           200,      /* where the window ends up on the screen */
           640,          /* The programs width */
           480,          /* and height in pixels */
           HWND_DESKTOP, /* The window is a child-window to desktop */
           NULL,         /* No menu */
           hThisInstance,/* Program Instance handler */
           NULL          /* No Window Creation data */
           ); 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0)) 
    {/* Translate virtual-key messages into character messages */
        TranslateMessage(&messages); 
        /* Send message to WindowProcedure */
        DispatchMessage(&messages); 
    } 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam; 
} 
//  
#define TestBorder 5

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
static POINT ptLast;
    POINT pt; 
    RECT rc;
    switch (message)
    { 
        case WM_NCHITTEST: 
			pt.x = LOWORD(lParam); 
			pt.y = HIWORD(lParam); 
			GetWindowRect(hwnd, &rc); 
 // move window
			rc.top+=TestBorder;
			rc.bottom-=TestBorder;
			rc.left+=TestBorder;
			rc.right-=TestBorder;
			if(PtInRect(&rc,pt))
			{
				return HTCAPTION; 
			}
// size window
			if (pt.x < rc.left && pt.y < rc.top)
			{ 
				return HTTOPLEFT; 
			} 
			if (pt.x>rc.right && pt.y<rc.top)
			{ 
				return HTTOPRIGHT; 
			} 
			if (pt.x<rc.left && pt.y>rc.bottom)
			{ 
				return HTBOTTOMLEFT; 
			} 
			if (pt.x>rc.right && pt.y>rc.bottom)
			{ 
				return HTBOTTOMRIGHT; 
			} 
			break; 
        case WM_CHAR:
			if((TCHAR) wParam == VK_RETURN) PostQuitMessage (0);       
            break; 
		case WM_MOUSEMOVE:
			pt.x = LOWORD(lParam);
			pt.y = HIWORD(lParam);  
			if(MK_LBUTTON==wParam)
			{
				GetWindowRect(hwnd,&rc);
				::MoveWindow(hwnd,rc.left+(pt.x-ptLast.x), rc.top+(pt.y-ptLast.y),
					rc.right-rc.left, rc.bottom-rc.top,TRUE);
			}
			else
			{
				ptLast=pt;
			}
		break;
        default: /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam); 
    } 
//  
    return 0; 
} 

非常感谢
PG_12138 2017-11-11
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
VC6 XP 下测试没有你所描述的问题 试试 wincl.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
试了一下,问题依然存在。我刚刚发现,QQ、酷狗、百度云的界面也存在这个问题。
schlafenhamster 2017-11-11
  • 打赏
  • 举报
回复
VC6 XP 下测试没有你所描述的问题 注意 要等 光标 变化 后 再 缩放 ! 另外 退出代码 如下 case WM_CHAR: if((TCHAR) wParam== 0x0D) PostQuitMessage (0); break;
zgl7903 2017-11-11
  • 打赏
  • 举报
回复
VC6 XP 下测试没有你所描述的问题 试试 wincl.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧