📄 deviceresolutionaware.h
字号:
// 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 + -