吵吵   2012-04-19  阅读:3,834

这个季节讨论的最多的无非是“考研”、“工作“、”毕业“这几个话题了。吵吵亲眼看过努力奋斗考研的人失败的情形,仿佛一瞬间黑了的天一样暗淡;也见过考上了但是最终却不去读了的人,纠结到神伤。找工作的人忙忙碌碌,考上研的孩子欢欢喜喜,终究是几家欢喜几家忧愁。

突然听到一些孩子考上的消息,他们正在无聊的等待着去上学;也听到一些找到工作的童鞋的消息,同样是无聊的等待着上班,好像人类的命运在此是交集的,都是一群无聊的人,干着一些无聊的事情而已。

一瞬间,我突然有种历尽沧桑的感觉,我也花费了不少个日日夜夜,奋战在考研的一线,也曾面试过,调剂过。然而最终选择工作这条路虽然不是我的刻意为之,多少也有点自我成分在里面。

曾经我问过她,为什么选择我,她说”你电脑好,我们辅导员说有个师兄就因为电脑好进了XX医院“。也许这是她的无心之言,多在说服她自己认为我是个潜力股,可当两年之后,我真的是因为电脑好进了XX医院,我便觉得一切都好似是宿命的安排。注定她当初的无心之语成就我的今日之行。惟一让我觉得留恋的是那时候的她真是单纯的可以。

当初用delphi写的第一个程序是实现了一个围绕鼠标旋转的文字,文字的内容是”祝XX永远开心幸福每一天“,遗憾的是我并没有完成这样一个承诺。当初也许是双方都想要的太多。现在倒是觉得人生简简单单的”有事做,有人爱,有所期待“便是最大的幸福。

delphi实现这样一个效果的思路是,搞了n个label控件,然后把属性改为透明。至于旋转的话,就自己写算法来移动那些label控件了。可是有个问题是delphi的控件刷新并非是双缓存输出的,于是就造成了文字闪烁的很厉害。于是我想用vc写,在移动的时候,并不去让其重绘。实现的思路如下:

1、建立白色背景的窗口,输出文字后利用updatelayedwindow函数将白色背景设为透明,以获得n个类似桌面歌词效果的窗口。我将其封装成了一个类,代码如下:

RoundText.h

class RoundText
{
public:
	RoundText(void);
	~RoundText(void);
protected:
	HWND m_hWnd;//窗口句柄
	HINSTANCE s_hInstance;//主程序句柄
	CString strText;
	int nFontSize;

public:
	bool Initialize(HINSTANCE hInstance);
	bool Create(HWND hParentWnd,CString str,int nSize);
	void ShowShadow();
	void MoveTheWindow(POINT pt);
protected:
	static LRESULT CALLBACK ChaoProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	void SetWindowAlpha(HDC hdcDst, POINT *pptDst,SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey,BLENDFUNCTION *pblend, DWORD dwFlags);
};

RoundText.cpp


#include "stdafx.h"
#include "Windows.h"
#include "RoundText.h"
//#include "wingdi.h"

RoundText:: RoundText(void)
	:m_hWnd((HWND)INVALID_HANDLE_VALUE)
{
	
}

RoundText::~RoundText(void)
{

}
LRESULT CALLBACK RoundText::ChaoProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	switch(uMsg)
	{

	case WM_PAINT:
		//AfxMessageBox(_T("ss"));
		break;
	}
	return ::DefWindowProc(hwnd,uMsg,wParam,lParam);
}
bool RoundText::Initialize(HINSTANCE hInstance)
{
	s_hInstance = hInstance;

	// Register window class for shadow window
	WNDCLASSEX wcex;

	memset(&wcex, 0, sizeof(wcex));

	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= ChaoProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	=  (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= _T("ChaoShadow");
	wcex.hIconSm		= NULL;

	RegisterClassEx(&wcex);

	return true;
}
bool RoundText::Create(HWND hParentWnd,CString str,int nSize)
{
	m_hWnd = CreateWindowEx(/*WS_EX_LAYERED | WS_EX_TRANSPARENT*/WS_EX_TOPMOST, _T("ChaoShadow"), NULL,
		 WS_POPUPWINDOW ,
		0,0, nSize, nSize, hParentWnd, NULL, s_hInstance, NULL);
    SetWindowLong(m_hWnd,GWL_EXSTYLE,GetWindowLong(m_hWnd,GWL_EXSTYLE)^0x80000);
	if(str.GetLength()!=1)
	{
		return false;
	}
	strText=str;
	
	nFontSize=nSize;
	
	return true;
}
void RoundText::ShowShadow()
{
	HDC  hDc= GetWindowDC(m_hWnd);
	SetTextColor(hDc,RGB(37,124,89));
	SetBkColor(hDc,RGB(255,255,255));

	
	HDC   hMen; 
	hMen   =   CreateCompatibleDC(NULL); 
	SetBkColor(hMen,RGB(255,255,255)); 
	HBITMAP   hBitmap; 
	hBitmap   =   CreateCompatibleBitmap(hMen,nFontSize,nFontSize);
	SelectObject(hMen,hBitmap);
	RECT   rect={0,0,nFontSize,nFontSize};
	HBRUSH   hBrushBg   =   CreateSolidBrush(RGB(255,255,255)); 
	FillRect(hMen,   &rect,   hBrushBg); 
	DeleteObject(hBrushBg);
	HFONT hFont;
	//创建字体
	hFont=CreateFont(nFontSize,0,0,0,800,false,false,0,
		ANSI_CHARSET,OUT_CHARACTER_PRECIS,
		CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
		DEFAULT_PITCH | FF_SWISS,_T("华文行楷"));
	SelectObject(hMen,hFont);
	TextOut(hMen,0,0,strText,1);
	DeleteObject(hFont);
	BitBlt(hDc,0,0,100,100,hMen,0,0,SRCCOPY);
	POINT pDst={0,0};
	POINT PSrc={0,0};
	SIZE mySize={nFontSize,nFontSize};
	BLENDFUNCTION blendPixelFunction= { AC_SRC_OVER, 0, 0, AC_SRC_ALPHA };
	SetWindowAlpha(hDc,&pDst, &mySize,hMen,&PSrc,RGB(255,255,255),&blendPixelFunction,1);
	ShowWindow(m_hWnd,SW_SHOW);
	ReleaseDC(m_hWnd,hDc);
	

}
void RoundText::MoveTheWindow(POINT pt)
{
	MoveWindow(m_hWnd,pt.x,pt.y,nFontSize,nFontSize,false);
}
void RoundText::SetWindowAlpha( HDC hdcDst, POINT *pptDst,SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey,BLENDFUNCTION *pblend, DWORD dwFlags)
{
	HINSTANCE hInst = LoadLibrary(_T("User32.DLL")); 
	if(hInst)
	{ 
		typedef BOOL (WINAPI *pfnUpdateLayeredWindow)(HWND hWnd, HDC hdcDst, POINT *pptDst,
			SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey,
			BLENDFUNCTION *pblend, DWORD dwFlags); 
		pfnUpdateLayeredWindow fun = NULL;
		fun = (pfnUpdateLayeredWindow)GetProcAddress(hInst, "UpdateLayeredWindow");
		if (fun)
		{

			fun(this->m_hWnd,   hdcDst, pptDst,psize, hdcSrc, pptSrc, crKey,pblend, dwFlags);
			FreeLibrary(hInst); 

		}
	}
}

2、创建一个隐藏主窗口,然后设定一个计时器,利用getcursorpos()函数来获得鼠标的位置。之后利用sin和cos乘以半径来设定各个透明文字窗口的位置,实现文字窗口的环绕效果。代码如下:


BOOL CChaoRoundTextDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	CString strToShow=_T("吵吵祝您开心幸福每一天!");
	nFontSize=50;
	NstrNum=strToShow.GetLength();
	CString *mystr;
	mystr= new CString[NstrNum];
	
	for (int i=0;i<NstrNum;i++)
	{
		mystr[i]=strToShow.Mid(i,1);

		myRoundText[i]=new RoundText;
		myRoundText[i]->Initialize(AfxGetInstanceHandle());
		myRoundText[i]->Create(this->GetSafeHwnd(),mystr[i],nFontSize);
		myRoundText[i]->ShowShadow();
	}

	this->SetTimer(1,10,NULL);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CChaoRoundTextDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	fMoveStep+=3.1415926/500;
	POINT ptMouse;
	GetCursorPos(&ptMouse);
	if(Rstep==100)
	{
		RstepDerect=2;
	}
	if(Rstep==300)
	{
		RstepDerect=-2;
	}
	Rstep+=RstepDerect;
	for(int i=0;i<NstrNum;i++)
	{
		POINT pt;
		pt.x=ptMouse.x+sin((i*(3.1415926*2/NstrNum)+fMoveStep))*Rstep-nFontSize/2;
		pt.y=ptMouse.y+cos((i*(3.1415926*2/NstrNum)+fMoveStep))*Rstep-nFontSize/2;
		myRoundText[i]->MoveTheWindow(pt);
	}
	//myRoundText.MoveTheWindow(mypt);
	
	CDialogEx::OnTimer(nIDEvent);
}

到此,我们的设计得以实现了,你可以看到”吵吵祝您开心幸福每一天!“的文字围绕你的鼠标环绕,同时又若即若离的扩散开去,又聚集回来。盯着他看了很久,不知道能够发给谁了。

vc

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

2条回应:“vc实现文字环绕鼠标旋转效果”

  1. 影楼营销说道:

    谢谢博主分享了啊

  2. 屠龙说道:

    分享分享!

发表评论

电子邮件地址不会被公开。 必填项已用*标注