可移动窗口

基于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还是很清晰的,至少可以知道自己在做什么。

虽然得自己手写消息映射=。=

完整代码:

http://img.ask.csdn.net/upload/201610/16/1476620294_424880.png

改为RAR即可打开


Keep it simple!
作者:N3verL4nd
知识共享,欢迎转载。
原文地址:https://www.cnblogs.com/lgh1992314/p/6616343.html