mirror of
https://github.com/reactos/reactos.git
synced 2024-11-09 16:20:37 +00:00
435a566751
* sumatrapdf - vendor import * everything compiles (libjpeg, poppler, fitz, sumatrapdf) * does NOT link (remove the comment tags in the parent directory.rbuild file (rosapps dir) to build it) svn path=/trunk/; revision=29295
634 lines
17 KiB
C
634 lines
17 KiB
C
/*++
|
|
|
|
Copyright (c) 2003 Microsoft Corporation
|
|
|
|
Abstract:
|
|
|
|
Helper functions for HIDPI/Landscape support.
|
|
|
|
--*/
|
|
|
|
#include "ms_ui_helper.h"
|
|
|
|
HIDPI_ENABLE;
|
|
|
|
BOOL HIDPI_StretchBitmap(
|
|
HBITMAP* phbm,
|
|
int cxDstImg,
|
|
int cyDstImg,
|
|
int cImagesX,
|
|
int cImagesY
|
|
)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
HBITMAP hbmNew;
|
|
BITMAP bm;
|
|
HDC hdcSrc, hdcDst, hdcScreen;
|
|
HBITMAP hbmOldSrc, hbmOldDst;
|
|
int cxSrcImg, cySrcImg;
|
|
int i, j, xDest, yDest, xBmp, yBmp;
|
|
|
|
if (!phbm || !*phbm || (cxDstImg == 0 && cyDstImg == 0) || (cImagesX == 0 || cImagesY == 0))
|
|
goto donestretch;
|
|
|
|
if ((sizeof(bm) != GetObject(*phbm, sizeof(bm), &bm)))
|
|
goto donestretch;
|
|
|
|
// If you hit this ASSERT, that mean your passed in image count in row and
|
|
// the column number of images is not correct.
|
|
// ASSERT(((bm.bmWidth % cImagesX) == 0) && ((bm.bmHeight % cImagesY) == 0));
|
|
|
|
cxSrcImg = bm.bmWidth / cImagesX;
|
|
cySrcImg = bm.bmHeight / cImagesY;
|
|
|
|
if (cxSrcImg == cxDstImg && cySrcImg == cyDstImg)
|
|
{
|
|
fRet = TRUE;
|
|
goto donestretch;
|
|
}
|
|
|
|
if (cxDstImg == 0)
|
|
cxDstImg = HIDPIMulDiv(cyDstImg, cxSrcImg, cySrcImg);
|
|
else if (cyDstImg == 0)
|
|
cyDstImg = HIDPIMulDiv(cxDstImg, cySrcImg, cxSrcImg);
|
|
|
|
hdcSrc = CreateCompatibleDC(NULL);
|
|
hdcDst = CreateCompatibleDC(NULL);
|
|
hdcScreen = GetDC(NULL);
|
|
hbmOldSrc = (HBITMAP)SelectObject(hdcSrc, *phbm);
|
|
hbmNew = CreateCompatibleBitmap(hdcScreen, cxDstImg * cImagesX, cyDstImg * cImagesY);
|
|
hbmOldDst = (HBITMAP)SelectObject(hdcDst, hbmNew);
|
|
ReleaseDC(NULL, hdcScreen);
|
|
|
|
// BLAST!
|
|
for (j = 0, yDest = 0, yBmp = 0; j < cImagesY; j++, yDest += cyDstImg, yBmp += cySrcImg)
|
|
{
|
|
for (i = 0, xDest = 0, xBmp = 0; i < cImagesX; i++, xDest += cxDstImg, xBmp += cxSrcImg)
|
|
{
|
|
StretchBlt(hdcDst, xDest, yDest, cxDstImg, cyDstImg,
|
|
hdcSrc, xBmp, yBmp, cxSrcImg, cySrcImg,
|
|
SRCCOPY);
|
|
}
|
|
}
|
|
|
|
// Free allocated memory
|
|
SelectObject(hdcSrc, hbmOldSrc);
|
|
SelectObject(hdcDst, hbmOldDst);
|
|
DeleteDC(hdcSrc);
|
|
DeleteDC(hdcDst);
|
|
|
|
// Delete the passed in bitmap
|
|
DeleteObject(*phbm);
|
|
*phbm = hbmNew;
|
|
|
|
fRet = TRUE;
|
|
|
|
donestretch:
|
|
return fRet;
|
|
}
|
|
|
|
static BOOL HIDPI_StretchIcon_Internal(
|
|
HICON hiconIn,
|
|
HICON* phiconOut,
|
|
int cxIcon,
|
|
int cyIcon
|
|
)
|
|
{
|
|
ICONINFO iconinfo;
|
|
|
|
HDC hdc;
|
|
HBITMAP hbmImage, hbmMask;
|
|
HBITMAP hbmOld;
|
|
BOOL fDrawMaskOK;
|
|
BOOL fDrawImageOK;
|
|
|
|
*phiconOut = NULL;
|
|
hdc = CreateCompatibleDC(NULL);
|
|
|
|
hbmMask = CreateCompatibleBitmap(hdc, cxIcon, cyIcon);
|
|
hbmOld = (HBITMAP)SelectObject(hdc, hbmMask);
|
|
fDrawMaskOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_MASK);
|
|
SelectObject(hdc, hbmOld);
|
|
|
|
hbmImage = CreateBitmap(cxIcon, cyIcon, 1, GetDeviceCaps(hdc, BITSPIXEL), NULL);
|
|
hbmOld = (HBITMAP)SelectObject(hdc, hbmImage);
|
|
fDrawImageOK = DrawIconEx(hdc, 0, 0, hiconIn, cxIcon, cyIcon, 0, NULL, DI_IMAGE);
|
|
SelectObject(hdc, hbmOld);
|
|
|
|
if (fDrawImageOK && fDrawMaskOK)
|
|
{
|
|
iconinfo.fIcon = TRUE;
|
|
iconinfo.hbmColor = hbmImage;
|
|
iconinfo.hbmMask = hbmMask;
|
|
*phiconOut = CreateIconIndirect(&iconinfo);
|
|
}
|
|
|
|
DeleteObject(hbmImage);
|
|
DeleteObject(hbmMask);
|
|
|
|
DeleteDC(hdc);
|
|
|
|
return (fDrawImageOK && fDrawMaskOK && *phiconOut != NULL) ? TRUE : FALSE;
|
|
}
|
|
|
|
BOOL HIDPI_StretchIcon(
|
|
HICON* phic,
|
|
int cxIcon,
|
|
int cyIcon
|
|
)
|
|
{
|
|
HICON hiconOut;
|
|
|
|
if (HIDPI_StretchIcon_Internal(*phic, &hiconOut, cxIcon, cyIcon))
|
|
{
|
|
DestroyIcon(*phic);
|
|
*phic = hiconOut;
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL HIDPI_GetBitmapLogPixels(
|
|
HINSTANCE hinst,
|
|
LPCTSTR lpbmp,
|
|
int* pnLogPixelsX,
|
|
int* pnLogPixelsY
|
|
)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
HRSRC hResource;
|
|
HGLOBAL hResourceBitmap = NULL;
|
|
BITMAPINFO* pBitmapInfo;
|
|
int PelsPerMeterX, PelsPerMeterY;
|
|
|
|
*pnLogPixelsX = 0;
|
|
*pnLogPixelsY = 0;
|
|
|
|
hResource = FindResource(hinst, lpbmp, RT_BITMAP);
|
|
if (!hResource)
|
|
{
|
|
goto error;
|
|
}
|
|
hResourceBitmap = LoadResource(hinst, hResource);
|
|
if (!hResourceBitmap)
|
|
{
|
|
goto error;
|
|
}
|
|
pBitmapInfo = (BITMAPINFO*)LockResource(hResourceBitmap);
|
|
if (!pBitmapInfo)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
// There are at least three kind value of PslsPerMeter used for 96 DPI bitmap:
|
|
// 0 - the bitmap just simply doesn't set this value
|
|
// 2834 - 72 DPI
|
|
// 3780 - 96 DPI
|
|
// So any value of PslsPerMeter under 3780 should be treated as 96 DPI bitmap.
|
|
PelsPerMeterX = (pBitmapInfo->bmiHeader.biXPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biXPelsPerMeter;
|
|
PelsPerMeterY = (pBitmapInfo->bmiHeader.biYPelsPerMeter < 3780) ? 3780 : pBitmapInfo->bmiHeader.biYPelsPerMeter;
|
|
|
|
// The formula for converting PelsPerMeter to LogPixels(DPI) is:
|
|
// LogPixels = PelsPerMeter / 39.37
|
|
// ( PelsPerMeter : Pixels per meter )
|
|
// ( LogPixels : Pixels per inch )
|
|
// Note: We need to round up.
|
|
*pnLogPixelsX = (int)((PelsPerMeterX * 100 + 1968) / 3937);
|
|
*pnLogPixelsY = (int)((PelsPerMeterY * 100 + 1968) / 3937);
|
|
|
|
fRet = TRUE;
|
|
|
|
error:
|
|
return fRet;
|
|
}
|
|
|
|
|
|
HIMAGELIST HIDPI_ImageList_LoadImage(
|
|
HINSTANCE hinst,
|
|
LPCTSTR lpbmp,
|
|
int cx,
|
|
int cGrow,
|
|
COLORREF crMask,
|
|
UINT uType,
|
|
UINT uFlags
|
|
)
|
|
{
|
|
HBITMAP hbmImage = NULL;
|
|
HIMAGELIST piml = NULL;
|
|
BITMAP bm;
|
|
int cImages, cxImage, cy;
|
|
int BmpLogPixelsX, BmpLogPixelsY;
|
|
UINT flags;
|
|
|
|
if ((uType != IMAGE_BITMAP) || // Image type is not IMAGE_BITMAP
|
|
(cx == 0)) // Caller doesn't care about the dimensions of the image - assumes the ones in the file
|
|
{
|
|
piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
|
|
goto cleanup;
|
|
}
|
|
|
|
if (!HIDPI_GetBitmapLogPixels(hinst, lpbmp, &BmpLogPixelsX, &BmpLogPixelsY))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
hbmImage = (HBITMAP)LoadImage(hinst, lpbmp, uType, 0, 0, uFlags);
|
|
if (!hbmImage || (sizeof(bm) != GetObject(hbmImage, sizeof(bm), &bm)))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
// do we need to scale this image?
|
|
if (BmpLogPixelsX == g_HIDPI_LogPixelsX)
|
|
{
|
|
piml = ImageList_LoadImage(hinst, lpbmp, cx, cGrow, crMask, uType, uFlags);
|
|
goto cleanup;
|
|
}
|
|
|
|
cxImage = HIDPIMulDiv(cx, BmpLogPixelsX, g_HIDPI_LogPixelsX);
|
|
|
|
// Bitmap width should be multiple integral of image width.
|
|
// If not, that means either your bitmap is wrong or passed in cx is wrong.
|
|
// ASSERT((bm.bmWidth % cxImage) == 0);
|
|
|
|
cImages = bm.bmWidth / cxImage;
|
|
|
|
cy = HIDPIMulDiv(bm.bmHeight, g_HIDPI_LogPixelsY, BmpLogPixelsY);
|
|
|
|
if ((g_HIDPI_LogPixelsX % BmpLogPixelsX) == 0)
|
|
{
|
|
HIDPI_StretchBitmap(&hbmImage, cx * cImages, cy, 1, 1);
|
|
}
|
|
else
|
|
{
|
|
// Here means the DPI is not integral multiple of standard DPI (96DPI).
|
|
// So if we stretch entire bitmap together, we are not sure each indivisual
|
|
// image will be stretch to right place. It is controled by StretchBlt().
|
|
// (for example, a 16 pixel icon, the first one might be stretch to 22 pixels
|
|
// and next one might be stretched to 20 pixels)
|
|
// What we have to do here is stretching indivisual image separately to make sure
|
|
// every one is stretched properly.
|
|
HIDPI_StretchBitmap(&hbmImage, cx, cy, cImages, 1);
|
|
}
|
|
|
|
flags = 0;
|
|
// ILC_MASK is important for supporting CLR_DEFAULT
|
|
if (crMask != CLR_NONE)
|
|
{
|
|
flags |= ILC_MASK;
|
|
}
|
|
// ILC_COLORMASK bits are important if we ever want to Merge ImageLists
|
|
if (bm.bmBits)
|
|
{
|
|
flags |= (bm.bmBitsPixel & ILC_COLORMASK);
|
|
}
|
|
|
|
// bitmap MUST be de-selected from the DC
|
|
// create the image list of the size asked for.
|
|
piml = ImageList_Create(cx, cy, flags, cImages, cGrow);
|
|
|
|
if (piml)
|
|
{
|
|
int added;
|
|
|
|
if (crMask == CLR_NONE)
|
|
{
|
|
added = ImageList_Add(piml, hbmImage, NULL);
|
|
}
|
|
else
|
|
{
|
|
added = ImageList_AddMasked(piml, hbmImage, crMask);
|
|
}
|
|
|
|
if (added < 0)
|
|
{
|
|
ImageList_Destroy(piml);
|
|
piml = NULL;
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
DeleteObject(hbmImage);
|
|
return piml;
|
|
}
|
|
|
|
int HIDPI_ImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
|
|
{
|
|
int iRet;
|
|
int cxIcon, cyIcon;
|
|
HICON hiconStretched;
|
|
|
|
ImageList_GetIconSize(himl, &cxIcon, &cyIcon);
|
|
HIDPI_StretchIcon_Internal(hicon, &hiconStretched, cxIcon, cyIcon);
|
|
if (hiconStretched != NULL)
|
|
{
|
|
iRet = ImageList_ReplaceIcon(himl, i, hiconStretched);
|
|
DestroyIcon(hiconStretched);
|
|
}
|
|
else
|
|
{
|
|
iRet = ImageList_ReplaceIcon(himl, i, hicon);
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
BOOL HIDPI_RectangleInternal(HDC hdc, int nLeft, int nTop, int nRight, int nBottom, int nThickness)
|
|
{
|
|
int nOff = nThickness/2;
|
|
|
|
nLeft += nOff;
|
|
nTop += nOff;
|
|
nRight -= nOff;
|
|
nBottom -= nOff;
|
|
|
|
return Rectangle(hdc, nLeft, nTop, nRight, nBottom);
|
|
}
|
|
|
|
#define BORDERX_PEN 32
|
|
|
|
BOOL HIDPI_BorderRectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
|
|
{
|
|
HPEN hpenOld;
|
|
BOOL bRet;
|
|
|
|
hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
|
|
bRet = HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, GetSystemMetrics(SM_CXBORDER));
|
|
SelectObject(hdc, hpenOld);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL HIDPI_Rectangle(HDC hdc, int nLeft, int nTop, int nRight, int nBottom)
|
|
{
|
|
LOGPEN lpenSel;
|
|
HPEN hpenSel;
|
|
|
|
// Obtain current pen thickness
|
|
hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
|
|
GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
|
|
|
|
return HIDPI_RectangleInternal(hdc, nLeft, nTop, nRight, nBottom, lpenSel.lopnWidth.x);
|
|
}
|
|
|
|
|
|
BOOL HIDPI_PolylineInternal(HDC hdc, const POINT *lppt, int cPoints, int nStyle, int nThickness)
|
|
{
|
|
int i;
|
|
int nHOff = 0, nVOff = 0;
|
|
BOOL bRet = TRUE;
|
|
POINT pts[2];
|
|
|
|
if (! (nStyle & PS_BIAS_MASK))
|
|
{
|
|
// No drawing bias. Draw normally
|
|
return Polyline(hdc, lppt, cPoints);
|
|
}
|
|
|
|
// Make sure caller didn't try to get both a left and a right bias or both a down and an up bias
|
|
// ASSERT(!(nStyle & PS_LEFTBIAS) || !(nStyle & PS_RIGHTBIAS));
|
|
// ASSERT(!(nStyle & PS_UPBIAS) || !(nStyle & PS_DOWNBIAS));
|
|
|
|
if (nStyle & PS_LEFTBIAS)
|
|
{
|
|
nHOff = -((nThickness-1)/2);
|
|
}
|
|
|
|
if (nStyle & PS_RIGHTBIAS)
|
|
{
|
|
nHOff = nThickness/2;
|
|
}
|
|
|
|
if (nStyle & PS_UPBIAS)
|
|
{
|
|
nVOff = -((nThickness-1)/2);
|
|
}
|
|
|
|
if (nStyle & PS_DOWNBIAS)
|
|
{
|
|
nVOff = nThickness/2;
|
|
}
|
|
|
|
for (i = 1; i < cPoints; i++)
|
|
{
|
|
// Use the two points that specify current line segment
|
|
memcpy(pts, &lppt[i-1], 2*sizeof(POINT));
|
|
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 = bRet && Polyline(hdc, pts, 2);
|
|
if (!bRet)
|
|
{
|
|
goto Error;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
return bRet;
|
|
}
|
|
|
|
BOOL HIDPI_BorderPolyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
|
|
{
|
|
HPEN hpenOld;
|
|
BOOL bRet;
|
|
|
|
hpenOld = (HPEN)SelectObject(hdc, (HPEN) GetStockObject(BORDERX_PEN));
|
|
bRet = HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, GetSystemMetrics(SM_CXBORDER));
|
|
SelectObject(hdc, hpenOld);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL HIDPI_Polyline(HDC hdc, const POINT *lppt, int cPoints, int nStyle)
|
|
{
|
|
LOGPEN lpenSel;
|
|
HPEN hpenSel;
|
|
|
|
// Obtain current pen thickness
|
|
hpenSel = (HPEN)GetCurrentObject(hdc, OBJ_PEN);
|
|
GetObject(hpenSel, sizeof(lpenSel), &lpenSel);
|
|
|
|
return HIDPI_PolylineInternal(hdc, lppt, cPoints, nStyle, lpenSel.lopnWidth.x);
|
|
}
|
|
|
|
//
|
|
// Called by RelayoutDialog to advance to the next item in the dialog template.
|
|
//
|
|
static LPBYTE WalkDialogData(LPBYTE lpData)
|
|
{
|
|
LPWORD lpWord = (LPWORD)lpData;
|
|
if (*lpWord == 0xFFFF)
|
|
{
|
|
return (LPBYTE)(lpWord + 2);
|
|
}
|
|
while (*lpWord != 0x0000)
|
|
{
|
|
lpWord++;
|
|
}
|
|
return (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.
|
|
//
|
|
static void FixupDialogItem(
|
|
HINSTANCE hInst,
|
|
HWND hDlg,
|
|
LPDLGITEMTEMPLATE lpDlgItem,
|
|
LPWORD lpClass,
|
|
LPWORD lpData)
|
|
{
|
|
if (lpClass[0] == 0xFFFF)
|
|
{
|
|
switch (lpClass[1])
|
|
{
|
|
case 0x0080: // button
|
|
case 0x0082: // static
|
|
{
|
|
if (lpData[0] == 0xFFFF)
|
|
{
|
|
if (lpDlgItem->style & SS_ICON)
|
|
{
|
|
HICON hOld = (HICON)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_ICON, 0);
|
|
HICON hNew = LoadIcon(hInst, MAKEINTRESOURCE(lpData[1]));
|
|
SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hNew);
|
|
DestroyIcon(hOld);
|
|
}
|
|
else if (lpDlgItem->style & SS_BITMAP)
|
|
{
|
|
HBITMAP hOld = (HBITMAP)SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_GETIMAGE, IMAGE_BITMAP, 0);
|
|
HBITMAP hNew = LoadBitmap(hInst, MAKEINTRESOURCE(lpData[1]));
|
|
SendDlgItemMessageW(hDlg, lpDlgItem->id, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hNew);
|
|
DeleteObject(hOld);
|
|
}
|
|
}
|
|
else // lpData[0] is not 0xFFFF (it's text).
|
|
{
|
|
SetDlgItemTextW(hDlg, lpDlgItem->id, (LPCTSTR)lpData);
|
|
}
|
|
}
|
|
break;
|
|
|
|
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;
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL RelayoutDialog(HINSTANCE hInst, HWND hDlg, LPCWSTR iddTemplate)
|
|
{
|
|
HRSRC hRsrc = FindResource((HMODULE)hInst, iddTemplate, RT_DIALOG);
|
|
INT nStatics = 0;
|
|
HGLOBAL hGlobal;
|
|
LPBYTE lpData;
|
|
LPDLGTEMPLATE lpTemplate;
|
|
HDWP hDWP;
|
|
int i;
|
|
LPDLGITEMTEMPLATE lpDlgItem;
|
|
HWND hwndCtl;
|
|
LPWORD lpClass;
|
|
WORD cbExtra;
|
|
|
|
if (hRsrc == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
hGlobal = LoadResource((HMODULE)hInst, hRsrc);
|
|
if (hGlobal == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
lpData = (LPBYTE)LockResource(hGlobal);
|
|
lpTemplate = (LPDLGTEMPLATE)lpData;
|
|
hDWP = BeginDeferWindowPos(lpTemplate->cdit);
|
|
|
|
//
|
|
// 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.
|
|
}
|
|
|
|
for (i = 0; i < lpTemplate->cdit; i++)
|
|
{
|
|
lpData = (LPBYTE) (((INT)lpData + 3) & ~3); // force to DWORD boundary.
|
|
lpDlgItem = (LPDLGITEMTEMPLATE)lpData;
|
|
hwndCtl = GetDlgItem(hDlg, lpDlgItem->id);
|
|
|
|
if (lpDlgItem->id == 0xFFFF)
|
|
{
|
|
nStatics++;
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
MapDialogRect(hDlg, &r);
|
|
DeferWindowPos(hDWP, hwndCtl, NULL,
|
|
r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER);
|
|
}
|
|
|
|
lpData += sizeof(DLGITEMTEMPLATE);
|
|
lpClass = (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, (LPWORD)lpData);
|
|
|
|
lpData = WalkDialogData(lpData); // title
|
|
cbExtra = *((LPWORD)lpData); // extra class data.
|
|
lpData += (cbExtra ? cbExtra : sizeof(WORD));
|
|
}
|
|
|
|
EndDeferWindowPos(hDWP);
|
|
return nStatics < 2 ? TRUE : FALSE;
|
|
}
|