基于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即可打开