win32 實現滾屏的兩種方式

代碼實現的優點粗燥,思路是這麼個思路。

方法1. 在timer裏面每次重畫窗口

LRESULT Demo::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_PAINT:
	{
		PAINTSTRUCT ps;
		RECT r;
		HDC hdc = BeginPaint(hWnd, &ps);
		HFONT hFont, hOldFont;
		GetClientRect(hWnd, &r);
		// 如果窗口顏色不是我們想要的,就填充一下以修改客戶區的顏色 
		HBRUSH hbr = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
		FillRect(hdc, &r, hbr);
		HDC hdcImage = ::CreateCompatibleDC(hdc);
		HBITMAP hBitmap = ::CreateCompatibleBitmap(hdc, r.right - r.left, r.bottom - r.top);//hdcImage
		HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hdcImage, hBitmap);
		LOGFONT logfont;
		ZeroMemory(&logfont, sizeof(LOGFONT));
		logfont.lfCharSet = DEFAULT_CHARSET;
		logfont.lfHeight = -36; 
		lstrcpy(logfont.lfFaceName, L"Arial");
		hFont = CreateFontIndirect(&logfont);
		if (hOldFont = (HFONT)SelectObject(hdcImage, hFont))
		{
			SetBkMode(hdcImage, TRANSPARENT);
			COLORREF color = RGB(255, 255, 255);
			::SetTextColor(hdcImage, color);
			size_t WLength = MultiByteToWideChar(CP_UTF8, 0, msg.C_str(), -1, NULL, NULL);
			LPWSTR pszW = (LPWSTR)_alloca((WLength + 1) * sizeof(WCHAR)); //do not need free
			MultiByteToWideChar(CP_UTF8, 0, msg.C_str(), -1, pszW, WLength);
			pszW[WLength] = 0;
			SIZE msgSize;
			::GetTextExtentPointW(hdcImage, pszW, WLength, &msgSize);
			HWND mainWnd = (HWND)*g_MainWnd;
			RECT rect;
			::GetClientRect(mainWnd, &r);
			rect.left = r.right - _msgStartPos;
			rect.top = (r.bottom - r.top - msgSize.cy) / 2;
			rect.right = rect.left + msgSize.cx;
			rect.bottom = rect.top + msgSize.cy; 
			//_msgStartPos 是這個類的全局變量,初始值是0.
			::TextOutW(hdcImage, r.right - _msgStartPos, (r.bottom - r.top - _msgSize.cy) / 2, pszW, WLength - 1);
			_msgStartPos += 20;
			if (_msgStartPos > r.right + _msgSize.cx)
			{
				::KillTimer(hWnd, 1);
				::ShowWindow(hWnd, SW_HIDE);
			}     
			SelectObject(hdcImage, hOldFont);
		}
		
		BitBlt(hdc, 0, 0, r.right - r.left, r.bottom - r.top, hdcImage, 0, 0, SRCPAINT);
		::SelectObject(hdcImage, hOldBitmap);
		DeleteObject(hBitmap);
		DeleteDC(hdcImage);
		DeleteObject(hFont);
		EndPaint(hWnd, &ps);

		return 1;
	}
	case WM_TIMER:
	{
		RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
	}
	break;

	default:
		break;
	}
	
	return DefWindowProc(hWnd, message, wParam, lParam);
}

方法2. 給窗口貼一個static,每次移動static的位置

LRESULT Demo::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_NCCREATE:
	{
		CREATESTRUCT* cs = (CREATESTRUCT*)lParam;
		LPVOID pWnd = cs->lpCreateParams;
		SetWindowLongPtr(hWnd, GWL_USERDATA, (LONG)pWnd);
		::PostMessageW(hWnd, WM_ERASEBKGND, 1, 0);
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	break;
	case WM_CREATE:
	{
		HFONT hFont;
		LOGFONT logfont;
		ZeroMemory(&logfont, sizeof(LOGFONT));
		logfont.lfCharSet = DEFAULT_CHARSET;
		logfont.lfHeight = -36; 
		lstrcpy(logfont.lfFaceName, L"Arial");
		hFont = CreateFontIndirect(&logfont);
		
		_msgStatic = CreateWindow(L"STATIC", L"", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
			0, 0, 1280, 56, hWnd, (HMENU)IDS_OVERLAY_MSG, NULL, NULL);
		_bkStatic = CreateWindow(L"STATIC", L"", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
			0, 0, 1280, 56, hWnd, (HMENU)IDS_OVERLAY_MSG, NULL, NULL);

		::PostMessageW(_msgStatic, WM_ERASEBKGND, 1, 0);
		::PostMessageW(_bkStatic, WM_ERASEBKGND, 1, 0);
		::PostMessageW(_msgStatic, WM_SETFONT, (WPARAM)hFont, 1);
	}
	break;
	case WM_CTLCOLORSTATIC:
	{
		SetTextColor((HDC)wParam, RGB(255, 255, 255));//set text color
		SetBkMode((HDC)wParam, TRANSPARENT);
		HBRUSH brush = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
		return (LONG)brush;
	}
	break;
	case WM_TIMER:
	{
		RECT wndRect;
		::GetClientRect(hWnd, &wndRect);
		// 要顯示的內容在這個函數外面已經set到了static上,具體方法參考方法1中的實現
		//_msgSize是在外面算好的,需要顯示的字符所佔的size
		SetWindowPos(_msgStatic, NULL, wndRect.right - _msgStartPos, (wndRect.bottom - wndRect.top - _msgSize.cy) / 2, _msgSize.cx, _msgSize.cy, SWP_NOZORDER);

		_msgStartPos += 20;

		if (_msgStartPos > wndRect.right + _msgSize.cx)
		{
			_msgStartPos = 0;
			::KillTimer(hWnd, 1);
			::ShowWindow(hWnd, SW_HIDE);
		}
	}
	break;
	default:
		break;
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章