基于VS2013+WTL9.1实现
// MoveableWindowView.h : interface of the CMoveableWindowView class
//
/
#pragma once
#include "MyWindow.h"
#include <GdiPlus.h>
using namespace Gdiplus;
class CMoveableWindowView : public CWindowImpl<CMoveableWindowView>,
public CDoubleBufferImpl<CMoveableWindowView>
{
public:
DECLARE_WND_CLASS(NULL)
CMoveableWindowView();
~CMoveableWindowView();
BOOL PreTranslateMessage(MSG* pMsg);
BEGIN_MSG_MAP(CMoveableWindowView)
//MESSAGE_HANDLER(WM_PAINT, OnPaint)
CHAIN_MSG_MAP(CDoubleBufferImpl<CMoveableWindowView>)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_SETCURSOR, OnCurosr)
END_MSG_MAP()
// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
//LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCurosr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
void DoPaint(CDCHandle dc); //解决绘图频闪
void setColor(int pen, int panel);
private:
GdiplusStartupInput gGdiInput; //gdi+
ULONG token; //gdi+
CMyWindow myWindow; //自定义窗口类
Point pushedPos; //记录鼠标的上一个按下位置
Point curPos; //鼠标当前位置
bool flag; //标记鼠标左键是否按下
Color penColor; //画笔颜色
Color panelColor; //画刷颜色
};
// MoveableWindowView.cpp : implementation of the CMoveableWindowView class
//
/
#include "stdafx.h"
#include "resource.h"
#include "MoveableWindowView.h"
#include <atlstr.h>
#include <atltypes.h>
#pragma comment(lib, "GdiPlus.lib")
CMoveableWindowView::CMoveableWindowView() : myWindow(1, 60, 100, 100, 400, 400)
{
token = 0;
flag = false;
pushedPos.X = 0;
pushedPos.Y = 0;
curPos.X = 0;
curPos.Y = 0;
GdiplusStartup(&token, &gGdiInput, NULL);
}
BOOL CMoveableWindowView::PreTranslateMessage(MSG* pMsg)
{
pMsg;
return FALSE;
}
void CMoveableWindowView::DoPaint(CDCHandle dc)
{
CRect rectClient;
GetClientRect(&rectClient);
//设置窗口背景色为白色
dc.FillSolidRect(rectClient, RGB(255, 255, 255));
Graphics g(dc.m_hDC);
Pen pen(Color(255, 0, 0, 255), 2.0f);
Rect rectDraw(myWindow.getLeft(), myWindow.getTop(), myWindow.getWidth(), myWindow.getHeight());
g.DrawRectangle(&pen, rectDraw);
g.DrawLine(&pen, myWindow.getLeft(), myWindow.getTop() + myWindow.getTHeight(), myWindow.getLeft() + myWindow.getWidth(), myWindow.getTop() + myWindow.getTHeight());
}
LRESULT CMoveableWindowView::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
/**
* 鼠标左击测试
CString str;
str.Format(TEXT("%d:%d"), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
MessageBox(str, TEXT("点击测试"));
*/
flag = true;
pushedPos.X = GET_X_LPARAM(lParam);
pushedPos.Y = GET_Y_LPARAM(lParam);
myWindow.onPress(pushedPos.X, pushedPos.Y);
return TRUE;
}
LRESULT CMoveableWindowView::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
curPos.X = GET_X_LPARAM(lParam);
curPos.Y = GET_Y_LPARAM(lParam);
//鼠标左键已按下
if (wParam & MK_LBUTTON)
{
RECT rect;
rect.left = myWindow.getLeft();
rect.top = myWindow.getTop();
rect.right = myWindow.getLeft() + myWindow.getWidth();
rect.bottom = myWindow.getTop() + myWindow.getHeight();
myWindow.onMove(curPos.X - pushedPos.X, curPos.Y - pushedPos.Y);
//闪瞎狗眼
InvalidateRect(NULL, true);
pushedPos.X = curPos.X;
pushedPos.Y = curPos.Y;
}
return TRUE;
}
LRESULT CMoveableWindowView::OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
flag = false;
curPos.X = GET_X_LPARAM(lParam);
curPos.Y = GET_Y_LPARAM(lParam);
pushedPos.X = 0;
pushedPos.Y = 0;
myWindow.onRelease(curPos.X, curPos.Y);
SetCursor(LoadCursor(NULL, IDC_ARROW));
return TRUE;
}
LRESULT CMoveableWindowView::OnCurosr(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
//鼠标左键按下则不再去更改鼠标外形
if (flag)
{
return FALSE;
}
int flag = myWindow.checkPos(curPos.X, curPos.Y);
switch (flag)
{
case CMyWindow::OTHER:
SetCursor(LoadCursor(NULL, IDC_ARROW));
break;
case CMyWindow::TITLE:
SetCursor(LoadCursor(NULL, IDC_HAND));
break;
case CMyWindow::TOP:
case CMyWindow::BOTTOM:
SetCursor(LoadCursor(NULL, IDC_SIZENS));
break;
case CMyWindow::LEFT:
case CMyWindow::RIGHT:
SetCursor(LoadCursor(NULL, IDC_SIZEWE));
break;
}
return TRUE;
}
CMoveableWindowView::~CMoveableWindowView()
{
GdiplusShutdown(token);
}
相比于MFC,WTL还是很清晰的,至少可以知道自己在做什么。
虽然得自己手写消息映射=。=
完整代码:
改为RAR即可打开