⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deviceresolutionaware.h

📁 用EVC编写的添加背景音乐程序,其中还有线程的创建和终止,很好的学习示例
💻 H
📖 第 1 页 / 共 3 页
字号:
//           PS_LEFTBIAS      PS_UPBIAS        PS_UPLEFT
//           PS_RIGHTBIAS     PS_DOWNBIAS      PS_DOWNRIGHT
//
//        These styles indicate how the pen should "hang" from each line
//        segment.  By default, the pen is centered along the line, but with
//        these line styles the developer can draw lines above, below, to the
//        left or to the right of the line segment.
//
// ON EXIT:
//     Returns TRUE on success, FALSE on failure.
//

const int PS_RIGHTBIAS = 0x10;
const int PS_LEFTBIAS  = 0x20;
const int PS_DOWNBIAS  = 0x40;
const int PS_UPBIAS    = 0x80;

const int PS_DOWNRIGHT = (PS_DOWNBIAS | PS_RIGHTBIAS);
const int PS_UPLEFT    = (PS_UPBIAS | PS_LEFTBIAS);
const int PS_BIAS_MASK = (PS_RIGHTBIAS | PS_LEFTBIAS | PS_DOWNBIAS | PS_UPBIAS);

inline BOOL Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
{
	// Make sure caller didn't try to get both a left and a right bias or both a down and an up bias

// glc
#if (_WIN32_WCE >= 501)
	_ASSERTE(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS));
	_ASSERTE(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS));
#else
	ASSERT(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS));
	ASSERT(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS));
#endif
	if(!(nStyle & PS_BIAS_MASK))
	{
		// No drawing bias. Draw normally
		return ::Polyline(hdc, lppt, cPoints);
	}

	// Obtain current pen thickness
	HPEN hpenSel = static_cast<HPEN>(::GetCurrentObject(hdc, OBJ_PEN));
	if(hpenSel == NULL)
	{
		return FALSE;
	}
	
	LOGPEN lpenSel;
	int iRet = ::GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
	if(iRet == 0)
	{
		return FALSE;
	}

	int nThickness = lpenSel.lopnWidth.x;

	int nHOff = 0;

	if(nStyle & PS_LEFTBIAS)
	{
		nHOff = -((nThickness-1)/2);
	}

	if(nStyle & PS_RIGHTBIAS)
	{
		nHOff = nThickness/2;
	}

	int nVOff = 0;

	if(nStyle & PS_UPBIAS)
	{
		nVOff = -((nThickness-1)/2);
	}

	if(nStyle & PS_DOWNBIAS)
	{
		nVOff = nThickness/2;
	}

	BOOL bRet = TRUE;
	POINT pts[2];

	for(int i = 1; i < cPoints; ++i)
	{
		// Use the two points that specify current line segment
		::memcpy(pts, &lppt[i-1], sizeof(pts));

		if(::abs(lppt[i].x - lppt[i-1].x) <= ::abs(lppt[i].y - lppt[i-1].y))
		{
			// Shift current line segment horizontally if abs(slope) >= 1
			pts[0].x += nHOff;
			pts[1].x += nHOff;
		}
		else
		{
			// Shift current line segment vertically if abs(slope) < 1
			pts[0].y += nVOff;
			pts[1].y += nVOff;
		}

		bRet = ::Polyline(hdc, pts, sizeof(pts)/sizeof(pts[0]));
		if(bRet == FALSE)
		{
			break;
		}
	}

	return bRet;
}

////////////////////////////////////////////////////////////////////////////////
// Orientation functions.
///////////////////////////////////////////////////////////////////////////////

//
// Called by RelayoutDialog to advance to the next item in the dialog template.
//
inline LPBYTE WalkDialogData(LPBYTE lpData)
{
	LPWORD lpWord = reinterpret_cast<LPWORD>(lpData);
	if(*lpWord == 0xFFFF)
	{
		return reinterpret_cast<LPBYTE>(lpWord + 2);
	}
	
	while(*lpWord != 0x0000)
	{
		++lpWord;
	}
	
	return reinterpret_cast<LPBYTE>(lpWord + 1);
}

//
// Post-processing step for each dialog item.
//    Static controls and buttons: change text and bitmaps.
//    Listboxes and combo boxes: ensures that the selected item is visible.
//
inline void FixupDialogItem(
	HINSTANCE hInst, 
	HWND hDlg, 
	LPDLGITEMTEMPLATE lpDlgItem, 
	LPWORD lpClass, 
	LPWORD lpData)
{
	if(lpClass[0] == 0xFFFF)
	{
		switch (lpClass[1])
		{
		case 0x0082: // static
			// glc
			//
			// Set the style and extended style, in case they differ between portrait and landscape.
			// This is common in Socket sofware, where labels that may be set as right-justified in
			// portrait mode may be set to centered or left-justified in landscape mode due to
			// text layout changes.

			SetWindowLong(GetDlgItem(hDlg, lpDlgItem->id), GWL_STYLE, lpDlgItem->style);
			SetWindowLong(GetDlgItem(hDlg, lpDlgItem->id), GWL_EXSTYLE, lpDlgItem->dwExtendedStyle);

			// fall thru to do the same as button, below...

		case 0x0080: // button
			{

			// glc
			//
			// The following case seems to allow for different graphics to appear in static controls
			// depending on the screen orientation. Interesting...

			if (lpData[0] == 0xFFFF)
			{
				// NOTE - SendDlgItemMessageW return code indicating failure
			
				if (FALSE) // glc ((lpDlgItem->style & SS_ICON) == SS_ICON)
				{
					HICON hNew = NULL;
					HICON hOld = reinterpret_cast<HICON>(::SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_ICON, 0));
					
					if (IsHiResScreen())
						hNew = (HICON)LoadImage(hInst, MAKEINTRESOURCE(lpData[1]), IMAGE_ICON, 64, 64, 0);
					else
						hNew = ::LoadIcon(hInst, MAKEINTRESOURCE(lpData[1]));

					if(hNew != NULL)
					{
						::SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hNew);
						::DestroyIcon(hOld); // Only delete hOld if we get a valid hNew, as it isn't allocated here, just replaced
					}
				}
				else if(((lpDlgItem->style & SS_BITMAP) == SS_BITMAP) && (IsHiResScreen()))
				{
					HBITMAP hOld = reinterpret_cast<HBITMAP>(::SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_BITMAP, 0));		
					HBITMAP hNew = NULL;
					int nHiBmpId;
					BOOL bRetVal;
					BITMAP bm;
					int nSize;
										
					//SetWindowLong(GetDlgItem(hDlg, lpDlgItem->id), GWL_STYLE, lpDlgItem->style | 0x00000800);

					nHiBmpId = GetWindowLong(GetDlgItem(hDlg, lpDlgItem->id), GWL_USERDATA);

					if (nHiBmpId)
						hNew= ::LoadBitmap(hInst, MAKEINTRESOURCE(nHiBmpId));

					if (!hNew)
					{
						hNew= ::LoadBitmap(hInst, MAKEINTRESOURCE(lpData[1]));
						nHiBmpId = 0;
					}

					if(hNew != NULL)
					{
						if (!nHiBmpId) // we may need to stretch the original
						{
							nSize = ::GetObject(hNew, sizeof(bm), &bm);
							StretchBitmap(&hNew, (bm.bmWidth*2), (bm.bmHeight*2), 1, 1);
						}
						nSize = ::GetObject(hNew, sizeof(bm), &bm);
						::SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hNew);
						::DeleteObject(hOld);  // Only delete hOld if we get a valid hNew, as it isn't allocated here, just replaced
						bRetVal = SetWindowPos(GetDlgItem(hDlg, lpDlgItem->id), 0, 0, 0, (bm.bmWidth), (bm.bmHeight), SWP_NOMOVE | SWP_NOZORDER);
					}
				}
			}
			else // lpData[0] is not 0xFFFF (it's text).
			{
				// glc
				//
				// This is interesting as it will allow portrait static controls to have different
				// text than landscape static controls, but this is probably mostly a pain, so
				// I've disabled it. It may be interesting to enable this someday

				//::SetDlgItemTextW(hDlg, lpDlgItem->id, (LPCTSTR)lpData);
			}
			
			break;
			
			}

		// This forces the list box to scroll into view in case it disappeared from view during the rotation.
		case 0x0083: // list box
			{

			INT nSel = ::SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_GETCURSEL, 0, 0);
			if(nSel != LB_ERR) 
			{
				::SendDlgItemMessageW(hDlg, lpDlgItem->id, LB_SETCURSEL, nSel, 0);
			}
			
			break;
			
			}

		// This forces the combo box to scroll into view in case it disappeared from view during the rotation.
		case 0x0085: // combo box
			{
				
			INT nSel = ::SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_GETCURSEL, 0, 0);
			if(nSel != CB_ERR) 
			{
				::SendDlgItemMessageW(hDlg, lpDlgItem->id, CB_SETCURSEL, nSel, 0);
			}
			
			break;
			
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////
// FUNCTION: RelayoutDialog
//
// PURPOSE: Re-lays out a dialog based on a dialog template.  This function
//      iterates through all the child window controls and does a SetWindowPos
//      for each.  It also does a SetWindowText for each static text control 
//      and updates the selected bitmap or icon in a static image control. 
//      This assumes that the current dialog and the new template have all the 
//      same controls, with the same IDCs.
//
// ON ENTRY:
//      HINSTANCE hInst: the hInstance of the current module.
//      HWND hDlg: the dialog to layout.
//      LPCWSTR iddTemplate: the new template for the dialog (can use 
//          the MAKEINTRESOURCE macro).
//
// ON EXIT: TRUE if success; FALSE if failure (either the iddTemplate is 
//      invalid, or there are two or more IDC_STATICs in the template).
//

inline BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate)
{
	HRSRC hRsrc = ::FindResource(static_cast<HMODULE>(hInst), iddTemplate, RT_DIALOG);
	if(hRsrc == NULL) 
	{
		return FALSE;
	}

	HGLOBAL hGlobal = ::LoadResource(static_cast<HMODULE>(hInst), hRsrc);
	if(hGlobal == NULL)
	{
		return FALSE;
	}

	LPBYTE lpData = reinterpret_cast<LPBYTE>(::LockResource(hGlobal));
	if(lpData == NULL)
	{
		return FALSE;
	}
	
	LPDLGTEMPLATE lpTemplate = reinterpret_cast<LPDLGTEMPLATE>(lpData);
	HDWP hDWP = ::BeginDeferWindowPos(lpTemplate->cdit);
	if(hDWP == NULL)
	{
		return FALSE;
	}

	//
	// For more information about the data structures that we are walking,
	// consult the DLGTEMPLATE and DLGITEMTEMPLATE documentation on MSDN.
	//
	lpData += sizeof(DLGTEMPLATE);
	lpData = WalkDialogData(lpData);     // menu
	lpData = WalkDialogData(lpData);     // class
	lpData = WalkDialogData(lpData);     // title

	if(lpTemplate->style & DS_SETFONT)
	{
		lpData += sizeof(WORD);          // font size.
		lpData = WalkDialogData(lpData); // font face.
	}

	INT nStatics = 0;
	BOOL bRet = TRUE;
	for(int i = 0; i < lpTemplate->cdit; i++)
	{
		lpData = reinterpret_cast<LPBYTE>(((INT)lpData + 3) & ~3);  // force to DWORD boundary.
		
		LPDLGITEMTEMPLATE lpDlgItem = reinterpret_cast<LPDLGITEMTEMPLATE>(lpData);
		
		HWND hwndCtl = ::GetDlgItem(hDlg, lpDlgItem->id);
		if(hwndCtl == NULL)
		{
			bRet = FALSE;
			continue;
		}

		//
		// Move the item around.
		//
		{
			
		RECT r;
		r.left   = lpDlgItem->x;
		r.top    = lpDlgItem->y;
		r.right  = lpDlgItem->x + lpDlgItem->cx;
		r.bottom = lpDlgItem->y + lpDlgItem->cy;
		
		BOOL bRet2 = ::MapDialogRect(hDlg, &r);
		if(bRet2 == FALSE)
		{
			bRet = FALSE;
			continue;
		}
		
		HDWP hdwp = ::DeferWindowPos(
			hDWP, 
			hwndCtl, 
			NULL, 
			r.left, 
			r.top, 
			r.right - r.left, 
			r.bottom - r.top, 
			SWP_NOZORDER);
		if(hdwp == NULL)
		{
			bRet = FALSE;
			// Note the failure but continue on anyway
		}
		
		}

		lpData += sizeof(DLGITEMTEMPLATE);
		LPWORD lpClass = reinterpret_cast<LPWORD>(lpData);
		lpData = WalkDialogData(lpData);  // class

		//
		// Do some special handling for each dialog item (changing text,
		// bitmaps, ensuring visible, etc.
		//
		FixupDialogItem(hInst, hDlg, lpDlgItem, lpClass, reinterpret_cast<LPWORD>(lpData));

		lpData = WalkDialogData(lpData);  // title        
		WORD cbExtra = *((LPWORD)lpData); // extra class data.
		lpData += (cbExtra ? cbExtra : sizeof(WORD));

		if(lpDlgItem->id == 0xFFFF)
		{
			++nStatics;
		}
	}

	// Be sure not to overwrite a FALSE value in bRet with a TRUE value from this call
	BOOL bRet2 = ::EndDeferWindowPos(hDWP);
	if(bRet2 == FALSE)
	{
		bRet = FALSE;
		
	}

	// Note failure if there was more then one item with an id of -1, as the items
	// will not have been matched up correctly.
	return nStatics < 2 ? bRet : FALSE;
}

} // namespace DRA

#endif // __DEVICERESOLUTIONAWARE_H__

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -