1208 lines
36 KiB
C++
1208 lines
36 KiB
C++
#include "ShowIcon.h"
|
|
|
|
HINSTANCE g_hInstance;
|
|
|
|
enum ICONVIEW
|
|
{
|
|
IV_ICON,
|
|
IV_MASK,
|
|
IV_COLOR,
|
|
IV_ALPHA
|
|
};
|
|
|
|
enum CURSORVIEW
|
|
{
|
|
CV_ICON,
|
|
CV_CURSOR,
|
|
CV_DEFAULT
|
|
};
|
|
|
|
enum LOADOPTIONS
|
|
{
|
|
LO_DEFAULT,
|
|
LO_REAL,
|
|
LO_16,
|
|
LO_32,
|
|
LO_48,
|
|
LO_64,
|
|
LO_96,
|
|
LO_128
|
|
};
|
|
|
|
enum DISPLAYOPTIONS
|
|
{
|
|
DO_NORMALDC,
|
|
DO_METAFILEDC,
|
|
DO_ENHMETAFILEDC
|
|
};
|
|
|
|
struct VIEWDATA
|
|
{
|
|
ICONINFO iconinfo;
|
|
HICON hIcon;
|
|
HCURSOR hIconCursor;
|
|
HCURSOR hDefaultCursor;
|
|
HBITMAP hbmpAlpha;
|
|
HBITMAP hbmpPreMultiplied; // Premultiplied version of the color bitmap.
|
|
HBRUSH hbrBackground;
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL CALLBACK ExtractIconDlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
static int * pcIcons = NULL;
|
|
|
|
switch(uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
pcIcons = (int *)lParam;
|
|
WCHAR strDesc[100];
|
|
wsprintf(strDesc, L"There are %d icons in this file.", *pcIcons);
|
|
SetDlgItemText(hwndDlg, IDC_EI_NUMICONS, strDesc);
|
|
SetDlgItemInt(hwndDlg, IDC_EI_ICONINDEX, 0, FALSE);
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
WORD wCommand = LOWORD(wParam);
|
|
switch(wCommand)
|
|
{
|
|
case IDOK:
|
|
{
|
|
BOOL fTranslated = FALSE;
|
|
|
|
*pcIcons = GetDlgItemInt(hwndDlg, IDC_EI_ICONINDEX, &fTranslated, FALSE);
|
|
if(!fTranslated || (*pcIcons < 0)) {
|
|
*pcIcons = -1;
|
|
}
|
|
}
|
|
EndDialog(hwndDlg, IDOK);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
*pcIcons = -1;
|
|
EndDialog(hwndDlg, IDCANCEL);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void GetBitmapSize(VIEWDATA & vd, DWORD & dwWidth, DWORD & dwHeight, bool & fAlpha)
|
|
{
|
|
BITMAP bmp;
|
|
|
|
if (vd.iconinfo.hbmColor != NULL) {
|
|
if (!GetObject(vd.iconinfo.hbmColor, sizeof(BITMAP), (LPSTR) &bmp)) {
|
|
bmp.bmWidth = 0;
|
|
bmp.bmHeight = 0;
|
|
bmp.bmBitsPixel = 0;
|
|
}
|
|
} else {
|
|
if (GetObject(vd.iconinfo.hbmMask, sizeof(BITMAP), (LPSTR) &bmp)) {
|
|
bmp.bmHeight /= 2;
|
|
} else {
|
|
bmp.bmWidth = 0;
|
|
bmp.bmHeight = 0;
|
|
bmp.bmBitsPixel = 0;
|
|
}
|
|
}
|
|
|
|
dwWidth = bmp.bmWidth;
|
|
dwHeight = bmp.bmHeight;
|
|
|
|
//
|
|
// Note: This just means that the bitmap MIGHT have an alpha channel.
|
|
//
|
|
fAlpha = (bmp.bmBitsPixel == 32 && bmp.bmPlanes == 1);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void SetShowIconTitle(HWND hwndMain, TCHAR * pszFileName, VIEWDATA & vd)
|
|
{
|
|
TCHAR szTitle[MAX_PATH * 2];
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha = false;
|
|
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
wsprintf(szTitle,
|
|
TEXT("ShowIcon [%dx%d] - %s"),
|
|
dwWidth,
|
|
dwHeight,
|
|
NULL == pszFileName ? TEXT("[Internal]") : pszFileName);
|
|
SetWindowText(hwndMain, szTitle);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void InitializeViewData(VIEWDATA & vd)
|
|
{
|
|
vd.hIcon = NULL;
|
|
vd.hIconCursor = NULL;
|
|
vd.hDefaultCursor = LoadCursor(NULL, IDC_ARROW);
|
|
vd.iconinfo.hbmColor = NULL;
|
|
vd.iconinfo.hbmMask = NULL;
|
|
vd.iconinfo.fIcon = TRUE;
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
vd.hbmpAlpha = NULL;
|
|
vd.hbmpPreMultiplied = NULL;
|
|
vd.hbrBackground = NULL;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void ClearViewData(VIEWDATA & vd)
|
|
{
|
|
if (vd.hIcon != NULL) {
|
|
DestroyIcon(vd.hIcon);
|
|
vd.hIcon = NULL;
|
|
}
|
|
|
|
if (vd.hIconCursor != NULL) {
|
|
DestroyCursor(vd.hIconCursor);
|
|
vd.hIconCursor = NULL;
|
|
}
|
|
|
|
if (vd.hDefaultCursor != NULL) {
|
|
DestroyCursor(vd.hDefaultCursor);
|
|
vd.hDefaultCursor = NULL;
|
|
}
|
|
|
|
if (vd.iconinfo.hbmColor != NULL) {
|
|
DeleteObject(vd.iconinfo.hbmColor);
|
|
vd.iconinfo.hbmColor = NULL;
|
|
}
|
|
|
|
if (vd.iconinfo.hbmMask != NULL) {
|
|
DeleteObject(vd.iconinfo.hbmMask);
|
|
vd.iconinfo.hbmMask = NULL;
|
|
}
|
|
|
|
vd.iconinfo.fIcon = TRUE;
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
|
|
if (vd.hbmpAlpha != NULL) {
|
|
DeleteObject(vd.hbmpAlpha);
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
|
|
if (vd.hbmpPreMultiplied != NULL) {
|
|
DeleteObject(vd.hbmpPreMultiplied);
|
|
vd.hbmpPreMultiplied = NULL;
|
|
}
|
|
|
|
if (vd.hbrBackground != NULL) {
|
|
DeleteObject(vd.hbrBackground);
|
|
vd.hbrBackground = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// This function takes an existing VIEWDATA structure, and rebuilds the
|
|
// ICONINFO data and hbmpAlpha from the already-loaded HICON.
|
|
//
|
|
void RefreshViewData(VIEWDATA & vd)
|
|
{
|
|
if (vd.hDefaultCursor == NULL) {
|
|
vd.hDefaultCursor = LoadCursor(NULL, IDC_ARROW);
|
|
}
|
|
|
|
if (vd.hbrBackground == NULL) {
|
|
LOGBRUSH lb;
|
|
lb.lbStyle = BS_HATCHED;
|
|
lb.lbColor = RGB(0, 0, 0);
|
|
lb.lbHatch = HS_BDIAGONAL;
|
|
vd.hbrBackground = CreateBrushIndirect(&lb);
|
|
}
|
|
|
|
if (vd.hIcon != NULL) {
|
|
//
|
|
// First, clear out any existing fields.
|
|
//
|
|
if (vd.iconinfo.hbmColor != NULL) {
|
|
DeleteObject(vd.iconinfo.hbmColor);
|
|
vd.iconinfo.hbmColor = NULL;
|
|
}
|
|
|
|
if (vd.iconinfo.hbmMask != NULL) {
|
|
DeleteObject(vd.iconinfo.hbmMask);
|
|
vd.iconinfo.hbmMask = NULL;
|
|
}
|
|
|
|
vd.iconinfo.fIcon = TRUE;
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
|
|
if (vd.hbmpAlpha != NULL) {
|
|
DeleteObject(vd.hbmpAlpha);
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
|
|
if (vd.hbmpPreMultiplied != NULL) {
|
|
DeleteObject(vd.hbmpPreMultiplied);
|
|
vd.hbmpPreMultiplied = NULL;
|
|
}
|
|
|
|
//
|
|
// Now get the new data.
|
|
//
|
|
GetIconInfo(vd.hIcon, &vd.iconinfo);
|
|
}
|
|
else if(vd.iconinfo.hbmColor != NULL)
|
|
{
|
|
//
|
|
// This appears to be a simple bitmap. There still might be an
|
|
// alpha channel.
|
|
//
|
|
// First, clear out any existing fields.
|
|
//
|
|
if (vd.iconinfo.hbmMask != NULL) {
|
|
DeleteObject(vd.iconinfo.hbmMask);
|
|
vd.iconinfo.hbmMask = NULL;
|
|
}
|
|
|
|
vd.iconinfo.fIcon = TRUE; // Well, certainly not a cursor.
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
|
|
if (vd.hbmpAlpha != NULL) {
|
|
DeleteObject(vd.hbmpAlpha);
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
|
|
if (vd.hbmpPreMultiplied != NULL) {
|
|
DeleteObject(vd.hbmpPreMultiplied);
|
|
vd.hbmpPreMultiplied = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Neither an icon, nor a bitmap. Bail.
|
|
//
|
|
return;
|
|
}
|
|
|
|
DWORD dwWidth;
|
|
DWORD dwHeight;
|
|
bool fAlpha;
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
//
|
|
// Create a bitmap to store a representation of the alpha channel.
|
|
//
|
|
if (fAlpha) {
|
|
BITMAPINFO bmi;
|
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bmi.bmiHeader.biWidth = dwWidth;
|
|
bmi.bmiHeader.biHeight = dwHeight;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biSizeImage = 0;
|
|
bmi.bmiHeader.biXPelsPerMeter = 0;
|
|
bmi.bmiHeader.biYPelsPerMeter = 0;
|
|
bmi.bmiHeader.biClrUsed = 0;
|
|
bmi.bmiHeader.biClrImportant = 0;
|
|
|
|
//
|
|
// We need the desktop DC for various reasons.
|
|
//
|
|
HDC hdc = GetDC(NULL);
|
|
|
|
//
|
|
// Create the bitmap and get back a pointer to where the actual
|
|
// bits are located.
|
|
//
|
|
RGBQUAD * pImageBits = NULL;
|
|
vd.hbmpAlpha = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **) &pImageBits, NULL, 0);
|
|
|
|
//
|
|
// Now, copy the bits from the icon image bitmap into our new bitmap.
|
|
//
|
|
if (0 != GetDIBits(hdc, vd.iconinfo.hbmColor, 0, dwHeight, pImageBits, &bmi, DIB_RGB_COLORS)) {
|
|
bool fAlphaUsed = false;
|
|
|
|
//
|
|
// Now, spin through the bitmap and look to see if the alpha
|
|
// channel is even used.
|
|
//
|
|
for(DWORD y = 0; y < dwHeight && !fAlphaUsed; y++) {
|
|
for(DWORD x = 0; x < dwWidth && !fAlphaUsed; x++) {
|
|
BYTE bAlpha = pImageBits[y*dwWidth + x].rgbReserved;
|
|
if (bAlpha != 0) {
|
|
fAlphaUsed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now, spin through the bitmap and create a grey-scale ramp
|
|
// that reflects the alpha channel.
|
|
//
|
|
if (fAlphaUsed) {
|
|
for(DWORD y = 0; y < dwHeight; y++) {
|
|
for(DWORD x = 0; x < dwWidth; x++) {
|
|
BYTE bAlpha = pImageBits[y*dwWidth + x].rgbReserved;
|
|
|
|
pImageBits[y*dwWidth + x].rgbRed = bAlpha;
|
|
pImageBits[y*dwWidth + x].rgbGreen = bAlpha;
|
|
pImageBits[y*dwWidth + x].rgbBlue = bAlpha;
|
|
pImageBits[y*dwWidth + x].rgbReserved = 0xFF;
|
|
}
|
|
}
|
|
} else {
|
|
//
|
|
// Clean up the unused alpha bitmap.
|
|
//
|
|
DeleteObject(vd.hbmpAlpha);
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// We're done with the desktop DC.
|
|
//
|
|
ReleaseDC(NULL, hdc);
|
|
}
|
|
|
|
//
|
|
// Create a bitmap to store the premultiplied version of the color bitmap.
|
|
//
|
|
if (fAlpha && vd.hbmpAlpha != NULL) {
|
|
BITMAPINFO bmi;
|
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bmi.bmiHeader.biWidth = dwWidth;
|
|
bmi.bmiHeader.biHeight = dwHeight;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biSizeImage = 0;
|
|
bmi.bmiHeader.biXPelsPerMeter = 0;
|
|
bmi.bmiHeader.biYPelsPerMeter = 0;
|
|
bmi.bmiHeader.biClrUsed = 0;
|
|
bmi.bmiHeader.biClrImportant = 0;
|
|
|
|
//
|
|
// We need the desktop DC for various reasons.
|
|
//
|
|
HDC hdc = GetDC(NULL);
|
|
|
|
//
|
|
// Create the bitmap and get back a pointer to where the actual
|
|
// bits are located.
|
|
//
|
|
RGBQUAD * pImageBits = NULL;
|
|
vd.hbmpPreMultiplied = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **) &pImageBits, NULL, 0);
|
|
|
|
//
|
|
// Now, copy the bits from the icon image bitmap into our new bitmap.
|
|
//
|
|
if (0 != GetDIBits(hdc, vd.iconinfo.hbmColor, 0, dwHeight, pImageBits, &bmi, DIB_RGB_COLORS)) {
|
|
//
|
|
// Now, spin through the bitmap and pre-multiply each pixel.
|
|
//
|
|
RGBQUAD pixel;
|
|
for(DWORD y = 0; y < dwHeight; y++) {
|
|
for(DWORD x = 0; x < dwWidth; x++) {
|
|
pixel = pImageBits[y*dwWidth + x];
|
|
|
|
pImageBits[y*dwWidth + x].rgbRed = (pixel.rgbRed * pixel.rgbReserved) / 0xFF;
|
|
pImageBits[y*dwWidth + x].rgbGreen = (pixel.rgbGreen * pixel.rgbReserved) / 0xFF;
|
|
pImageBits[y*dwWidth + x].rgbBlue = (pixel.rgbBlue * pixel.rgbReserved) / 0xFF;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// We're done with the desktop DC.
|
|
//
|
|
ReleaseDC(NULL, hdc);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void LoadViewData(VIEWDATA & vd, TCHAR * pszFileName, UINT fuLoad, LOADOPTIONS lo)
|
|
{
|
|
int x = 0;
|
|
int y = 0;
|
|
HINSTANCE hInstance = (fuLoad == LR_LOADFROMFILE ? NULL : g_hInstance);
|
|
|
|
ClearViewData(vd);
|
|
|
|
switch (lo) {
|
|
case LO_REAL:
|
|
x = 0;
|
|
y = 0;
|
|
break;
|
|
|
|
case LO_DEFAULT:
|
|
fuLoad |= LR_DEFAULTSIZE;
|
|
break;
|
|
|
|
case LO_16:
|
|
x = 16;
|
|
y = 16;
|
|
break;
|
|
|
|
case LO_32:
|
|
x = 32;
|
|
y = 32;
|
|
break;
|
|
|
|
case LO_48:
|
|
x = 48;
|
|
y = 48;
|
|
break;
|
|
|
|
case LO_64:
|
|
x = 64;
|
|
y = 64;
|
|
break;
|
|
|
|
case LO_96:
|
|
x = 96;
|
|
y = 96;
|
|
break;
|
|
|
|
case LO_128:
|
|
x = 128;
|
|
y = 128;
|
|
break;
|
|
}
|
|
|
|
vd.hIcon = (HICON) LoadImage(hInstance, pszFileName, IMAGE_ICON, x, y, fuLoad | LR_SHARED);
|
|
if (vd.hIcon != NULL) {
|
|
vd.hIconCursor = (HCURSOR) LoadImage(hInstance, pszFileName, IMAGE_CURSOR, x, y, fuLoad | LR_SHARED);
|
|
} else {
|
|
//
|
|
// Try to load the image as a bitmap...
|
|
//
|
|
vd.hIcon = NULL;
|
|
vd.hIconCursor = NULL;
|
|
vd.iconinfo.fIcon = TRUE; // Well, it certainly isn't a cursor....
|
|
vd.iconinfo.hbmColor = (HBITMAP) LoadImage(hInstance, pszFileName, IMAGE_BITMAP, x, y, fuLoad | LR_SHARED);
|
|
vd.iconinfo.hbmMask = NULL;
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
|
|
RefreshViewData(vd);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void ReLoadViewData(VIEWDATA & vd, UINT fuLoad, LOADOPTIONS lo)
|
|
{
|
|
int x = 0;
|
|
int y = 0;
|
|
HINSTANCE hInstance = (fuLoad == LR_LOADFROMFILE ? NULL : g_hInstance);
|
|
HICON hIcon = NULL;
|
|
HCURSOR hIconCursor = NULL;
|
|
HBITMAP hbmColor = NULL;
|
|
|
|
switch (lo) {
|
|
case LO_REAL:
|
|
x = 0;
|
|
y = 0;
|
|
break;
|
|
|
|
case LO_DEFAULT:
|
|
fuLoad |= LR_DEFAULTSIZE;
|
|
break;
|
|
|
|
case LO_16:
|
|
x = 16;
|
|
y = 16;
|
|
break;
|
|
|
|
case LO_32:
|
|
x = 32;
|
|
y = 32;
|
|
break;
|
|
|
|
case LO_48:
|
|
x = 48;
|
|
y = 48;
|
|
break;
|
|
|
|
case LO_64:
|
|
x = 64;
|
|
y = 64;
|
|
break;
|
|
|
|
case LO_96:
|
|
x = 96;
|
|
y = 96;
|
|
break;
|
|
|
|
case LO_128:
|
|
x = 128;
|
|
y = 128;
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Make copies of the exisitng icon and cursor.
|
|
//
|
|
if (vd.hIcon != NULL) {
|
|
hIcon = (HICON) CopyImage(vd.hIcon, IMAGE_ICON, x, y, fuLoad | LR_COPYFROMRESOURCE | LR_SHARED);
|
|
}
|
|
|
|
if (hIcon != NULL) {
|
|
if (vd.hIconCursor != NULL) {
|
|
hIconCursor = (HCURSOR) CopyImage(vd.hIconCursor, IMAGE_CURSOR, x, y, fuLoad | LR_COPYFROMRESOURCE | LR_SHARED);
|
|
}
|
|
} else {
|
|
if (vd.iconinfo.hbmColor != NULL) {
|
|
hbmColor = (HBITMAP) CopyImage(vd.iconinfo.hbmColor, IMAGE_BITMAP, x, y, fuLoad | LR_COPYFROMRESOURCE | LR_SHARED);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Nuke the existing draw data.
|
|
//
|
|
ClearViewData(vd);
|
|
|
|
vd.hIcon = hIcon;
|
|
if (vd.hIcon != NULL) {
|
|
vd.hIconCursor = hIconCursor;
|
|
} else {
|
|
//
|
|
// Try to load the image as a bitmap...
|
|
//
|
|
vd.hIcon = NULL;
|
|
vd.hIconCursor = NULL;
|
|
vd.iconinfo.fIcon = TRUE; // Well, it certainly isn't a cursor....
|
|
vd.iconinfo.hbmColor = hbmColor;
|
|
vd.iconinfo.hbmMask = NULL;
|
|
vd.iconinfo.xHotspot = 0;
|
|
vd.iconinfo.yHotspot = 0;
|
|
vd.hbmpAlpha = NULL;
|
|
}
|
|
|
|
RefreshViewData(vd);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
ICONVIEW SelectIconView(HMENU hMenu, int id)
|
|
{
|
|
MENUITEMINFO mii;
|
|
int rgMenuItems[] = { VIEW_ICON, VIEW_MASK, VIEW_COLOR, VIEW_ALPHA };
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_STATE;
|
|
|
|
for(int i = 0; i < sizeof(rgMenuItems) / sizeof(rgMenuItems[ 0 ]); i++) {
|
|
GetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
|
|
if (rgMenuItems[ i ] == id) {
|
|
if ((mii.fState & MFS_CHECKED) == 0) {
|
|
mii.fState |= MFS_CHECKED;
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
} else {
|
|
if (mii.fState & MFS_CHECKED) {
|
|
mii.fState &= (~MFS_CHECKED);
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (id) {
|
|
case VIEW_ICON:
|
|
default:
|
|
return IV_ICON;
|
|
|
|
case VIEW_MASK:
|
|
return IV_MASK;
|
|
|
|
case VIEW_COLOR:
|
|
return IV_COLOR;
|
|
|
|
case VIEW_ALPHA:
|
|
return IV_ALPHA;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CURSORVIEW SelectCursorView(HMENU hMenu, int id)
|
|
{
|
|
MENUITEMINFO mii;
|
|
int rgMenuItems[] = { VIEW_ICONCURSOR, VIEW_REALCURSOR, VIEW_DEFAULTCURSOR };
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_STATE;
|
|
|
|
for(int i = 0; i < sizeof(rgMenuItems) / sizeof(rgMenuItems[ 0 ]); i++) {
|
|
GetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
|
|
if (rgMenuItems[ i ] == id) {
|
|
if ((mii.fState & MFS_CHECKED) == 0) {
|
|
mii.fState |= MFS_CHECKED;
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
} else {
|
|
if (mii.fState & MFS_CHECKED) {
|
|
mii.fState &= (~MFS_CHECKED);
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (id) {
|
|
case VIEW_ICONCURSOR:
|
|
return CV_ICON;
|
|
|
|
case VIEW_REALCURSOR:
|
|
return CV_CURSOR;
|
|
|
|
case VIEW_DEFAULTCURSOR:
|
|
default:
|
|
return CV_DEFAULT;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LOADOPTIONS SelectLoadOptions(HMENU hMenu, int id)
|
|
{
|
|
MENUITEMINFO mii;
|
|
int rgMenuItems[] = { IDM_DEFAULT_SIZE, IDM_REAL_SIZE, IDM_SIZE_16, IDM_SIZE_32, IDM_SIZE_48, IDM_SIZE_64, IDM_SIZE_96, IDM_SIZE_128 };
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_STATE;
|
|
|
|
for(int i = 0; i < sizeof(rgMenuItems) / sizeof(rgMenuItems[ 0 ]); i++) {
|
|
GetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
|
|
if (rgMenuItems[ i ] == id) {
|
|
if ((mii.fState & MFS_CHECKED) == 0) {
|
|
mii.fState |= MFS_CHECKED;
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
} else {
|
|
if (mii.fState & MFS_CHECKED) {
|
|
mii.fState &= (~MFS_CHECKED);
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (id) {
|
|
case IDM_REAL_SIZE:
|
|
return LO_REAL;
|
|
|
|
case IDM_SIZE_16:
|
|
return LO_16;
|
|
|
|
case IDM_SIZE_32:
|
|
return LO_32;
|
|
|
|
case IDM_SIZE_48:
|
|
return LO_48;
|
|
|
|
case IDM_SIZE_64:
|
|
return LO_64;
|
|
|
|
case IDM_SIZE_96:
|
|
return LO_96;
|
|
|
|
case IDM_SIZE_128:
|
|
return LO_128;
|
|
|
|
case IDM_DEFAULT_SIZE:
|
|
default:
|
|
return LO_DEFAULT;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
DISPLAYOPTIONS SelectDisplayOptions(HMENU hMenu, int id)
|
|
{
|
|
MENUITEMINFO mii;
|
|
int rgMenuItems[] = { IDM_METAFILEDC, IDM_ENHMETAFILEDC, IDM_NORMALDC };
|
|
|
|
mii.cbSize = sizeof(MENUITEMINFO);
|
|
mii.fMask = MIIM_STATE;
|
|
|
|
for(int i = 0; i < sizeof(rgMenuItems) / sizeof(rgMenuItems[ 0 ]); i++) {
|
|
GetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
|
|
if (rgMenuItems[ i ] == id) {
|
|
if ((mii.fState & MFS_CHECKED) == 0) {
|
|
mii.fState |= MFS_CHECKED;
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
} else {
|
|
if (mii.fState & MFS_CHECKED) {
|
|
mii.fState &= (~MFS_CHECKED);
|
|
SetMenuItemInfo(hMenu, rgMenuItems[ i ], FALSE, &mii);
|
|
}
|
|
}
|
|
}
|
|
|
|
switch(id)
|
|
{
|
|
case IDM_METAFILEDC:
|
|
return DO_METAFILEDC;
|
|
break;
|
|
|
|
case IDM_ENHMETAFILEDC:
|
|
return DO_ENHMETAFILEDC;
|
|
break;
|
|
|
|
case IDM_NORMALDC:
|
|
default:
|
|
return DO_NORMALDC;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static VIEWDATA vd;
|
|
static TCHAR szFileName[MAX_PATH];
|
|
static ICONVIEW iv = IV_ICON;
|
|
static CURSORVIEW cv = CV_DEFAULT;
|
|
static LOADOPTIONS lo = LO_REAL;
|
|
static DISPLAYOPTIONS dop = DO_NORMALDC;
|
|
|
|
switch (message) {
|
|
case WM_CREATE:
|
|
InitializeViewData(vd);
|
|
szFileName[0] = '\0';
|
|
iv = IV_ICON;
|
|
cv = CV_DEFAULT;
|
|
lo = LO_REAL;
|
|
dop = DO_NORMALDC;
|
|
|
|
DragAcceptFiles(hWnd, TRUE);
|
|
LoadViewData(vd, szFileName, 0, lo);
|
|
SetShowIconTitle(hWnd, szFileName, vd);
|
|
break;
|
|
|
|
case WM_DROPFILES:
|
|
{
|
|
HDROP hdrop = (HDROP) wParam;
|
|
DragQueryFile(hdrop, 0, szFileName, MAX_PATH);
|
|
LoadViewData(vd, szFileName, LR_LOADFROMFILE, lo);
|
|
SetShowIconTitle(hWnd, szFileName, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
int wmId = LOWORD(wParam);
|
|
int wmEvent HIWORD(wParam);
|
|
|
|
switch (wmId) {
|
|
case IDM_DEFAULT_SIZE:
|
|
case IDM_REAL_SIZE:
|
|
case IDM_SIZE_16:
|
|
case IDM_SIZE_32:
|
|
case IDM_SIZE_48:
|
|
case IDM_SIZE_64:
|
|
case IDM_SIZE_96:
|
|
case IDM_SIZE_128:
|
|
lo = SelectLoadOptions(GetMenu(hWnd), wmId);
|
|
break;
|
|
|
|
case IDM_NORMALDC:
|
|
case IDM_METAFILEDC:
|
|
case IDM_ENHMETAFILEDC:
|
|
dop = SelectDisplayOptions(GetMenu(hWnd), wmId);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case VIEW_ICON:
|
|
case VIEW_MASK:
|
|
case VIEW_COLOR:
|
|
case VIEW_ALPHA:
|
|
iv = SelectIconView(GetMenu(hWnd), wmId);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case VIEW_REFRESH:
|
|
RefreshViewData(vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case VIEW_ICONCURSOR:
|
|
case VIEW_REALCURSOR:
|
|
case VIEW_DEFAULTCURSOR:
|
|
cv = SelectCursorView(GetMenu(hWnd), wmId);
|
|
break;
|
|
|
|
case IDM_EXIT:
|
|
DestroyWindow(hWnd);
|
|
break;
|
|
|
|
case IDM_SAMPLE16:
|
|
LoadViewData(vd, MAKEINTRESOURCE(IDI_SAMPLE16), LR_DEFAULTCOLOR, lo);
|
|
SetShowIconTitle(hWnd, NULL, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_SAMPLE32:
|
|
LoadViewData(vd, MAKEINTRESOURCE(IDI_SAMPLE32), LR_DEFAULTCOLOR, lo);
|
|
SetShowIconTitle(hWnd, NULL, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_SAMPLE64:
|
|
LoadViewData(vd, MAKEINTRESOURCE(IDI_SAMPLE64), LR_DEFAULTCOLOR, lo);
|
|
SetShowIconTitle(hWnd, NULL, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_APPICON:
|
|
LoadViewData(vd, MAKEINTRESOURCE(IDI_SHOWICON), LR_DEFAULTCOLOR, lo);
|
|
SetShowIconTitle(hWnd, NULL, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_MYCOMPUTER:
|
|
LoadViewData(vd, MAKEINTRESOURCE(IDI_MYCOMPUTER), LR_DEFAULTCOLOR, lo);
|
|
SetShowIconTitle(hWnd, NULL, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case IDM_FILE_OPEN:
|
|
{
|
|
OPENFILENAME ofn;
|
|
TCHAR * szFilter = TEXT("Icons (*.ico)\0*.ico\0")
|
|
TEXT("Cursors (*.cur)\0*.cur\0")
|
|
TEXT("Bitmaps (*.bmp)\0*.bmp\0")
|
|
TEXT("All Supported Formats (*.ico;*.cur;*.bmp)\0*.ico;*.cur;*.bmp\0")
|
|
TEXT("All Files (*.*)\0*.*\0");
|
|
szFileName[0] = TEXT('\0');
|
|
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hWnd;
|
|
ofn.hInstance = g_hInstance;
|
|
ofn.lpstrFilter = szFilter;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
|
ofn.lpstrDefExt = TEXT("*.ico");
|
|
|
|
if (GetOpenFileName(&ofn)) {
|
|
LoadViewData(vd, szFileName, LR_LOADFROMFILE, lo);
|
|
SetShowIconTitle(hWnd, szFileName, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_EXTRACTICON:
|
|
{
|
|
OPENFILENAME ofn;
|
|
TCHAR * szFilter = TEXT("Programs (*.exe)\0*.exe\0")
|
|
TEXT("DLLs (*.dll;*.ocx)\0*.dll;*.ocx\0")
|
|
TEXT("All Supported Formats (*.exe;*.dll;*.ocx)\0*.exe;*.dll;*.ocx\0")
|
|
TEXT("All Files (*.*)\0*.*\0");
|
|
|
|
szFileName[0] = TEXT('\0');
|
|
|
|
ZeroMemory(&ofn, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hWnd;
|
|
ofn.hInstance = g_hInstance;
|
|
ofn.lpstrFilter = szFilter;
|
|
ofn.lpstrFile = szFileName;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
|
ofn.lpstrDefExt = TEXT("*.exe");
|
|
|
|
if (GetOpenFileName(&ofn)) {
|
|
ClearViewData(vd);
|
|
int cIcons = (int) ExtractIconW(g_hInstance, szFileName, -1);
|
|
if (cIcons > 0) {
|
|
if(DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_EXTRACTICON), hWnd, ExtractIconDlgProc, LPARAM(&cIcons)) == IDOK) {
|
|
vd.hIcon = ExtractIconW(g_hInstance, szFileName, cIcons);
|
|
RefreshViewData(vd);
|
|
SetShowIconTitle(hWnd, szFileName, vd);
|
|
}
|
|
}
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_REOPEN:
|
|
{
|
|
ReLoadViewData(vd, 0, lo);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SO_LOADFILE:
|
|
LoadViewData(vd, (TCHAR*)lParam, LR_LOADFROMFILE, lo);
|
|
SetShowIconTitle(hWnd, (TCHAR*)lParam, vd);
|
|
InvalidateRgn(hWnd, NULL, TRUE);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdcWindow = BeginPaint(hWnd, &ps);
|
|
RECT rcClient;
|
|
HDC hdcPaint = NULL;
|
|
|
|
if (dop == DO_METAFILEDC) {
|
|
hdcPaint = CreateMetaFile(NULL);
|
|
} else if (dop == DO_ENHMETAFILEDC) {
|
|
hdcPaint = CreateEnhMetaFile(hdcWindow, NULL, NULL, NULL);
|
|
} else {
|
|
hdcPaint = hdcWindow;
|
|
}
|
|
|
|
GetClientRect(hWnd, &rcClient);
|
|
SetBrushOrgEx(hdcPaint, -5, -5, NULL);
|
|
SetBkColor(hdcPaint, RGB(128, 128, 128));
|
|
SetBkMode(hdcPaint, OPAQUE);
|
|
|
|
if (ps.fErase) {
|
|
FillRect(hdcPaint, &(ps.rcPaint), vd.hbrBackground);
|
|
}
|
|
|
|
if (iv == IV_ICON) {
|
|
//
|
|
// Draw either the icon, alpha-blended bitmap, or normal bitmap.
|
|
//
|
|
if (vd.hIcon != NULL) {
|
|
DrawIconEx(hdcPaint, 5, 5, vd.hIcon, rcClient.right - 10, rcClient.bottom - 10, 0, NULL, DI_NORMAL);
|
|
} else if(vd.hbmpPreMultiplied != NULL) {
|
|
HDC hdcBitmap = NULL;
|
|
HBITMAP hbmOld = NULL;
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha;
|
|
BLENDFUNCTION bf;
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
hdcBitmap = CreateCompatibleDC(hdcPaint);
|
|
hbmOld = (HBITMAP) SelectObject(hdcBitmap, vd.iconinfo.hbmColor);
|
|
bf.BlendOp = AC_SRC_OVER;
|
|
bf.BlendFlags = 0;
|
|
bf.SourceConstantAlpha = 255;
|
|
bf.AlphaFormat = AC_SRC_ALPHA;
|
|
AlphaBlend(hdcPaint, 5, 5, rcClient.right - 10, rcClient.bottom - 10, hdcBitmap, 0, 0, dwWidth, dwHeight, bf);
|
|
SelectObject(hdcBitmap, hbmOld);
|
|
DeleteDC(hdcBitmap);
|
|
} else if(vd.iconinfo.hbmColor != NULL) {
|
|
HDC hdcBitmap = NULL;
|
|
HBITMAP hbmOld = NULL;
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha;
|
|
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
hdcBitmap = CreateCompatibleDC(hdcPaint);
|
|
hbmOld = (HBITMAP) SelectObject(hdcBitmap, vd.iconinfo.hbmColor);
|
|
StretchBlt(hdcPaint, 5, 5, rcClient.right - 10, rcClient.bottom - 10, hdcBitmap, 0, 0, dwWidth, dwHeight, SRCCOPY);
|
|
SelectObject(hdcBitmap, hbmOld);
|
|
DeleteDC(hdcBitmap);
|
|
} else {
|
|
DrawText(hdcPaint, TEXT("No icon data to display"), -1, &rcClient, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
|
|
}
|
|
} else if (iv == IV_COLOR && vd.iconinfo.hbmColor != NULL) {
|
|
HDC hdcBitmap = NULL;
|
|
HBITMAP hbmOld = NULL;
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha;
|
|
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
hdcBitmap = CreateCompatibleDC(hdcPaint);
|
|
hbmOld = (HBITMAP) SelectObject(hdcBitmap, vd.iconinfo.hbmColor);
|
|
StretchBlt(hdcPaint, 5, 5, rcClient.right - 10, rcClient.bottom - 10, hdcBitmap, 0, 0, dwWidth, dwHeight, SRCCOPY);
|
|
SelectObject(hdcBitmap, hbmOld);
|
|
DeleteDC(hdcBitmap);
|
|
} else if (iv == IV_MASK && vd.iconinfo.hbmMask != NULL) {
|
|
HDC hdcBitmap = NULL;
|
|
HBITMAP hbmOld = NULL;
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha;
|
|
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
hdcBitmap = CreateCompatibleDC(hdcPaint);
|
|
hbmOld = (HBITMAP) SelectObject(hdcBitmap, vd.iconinfo.hbmMask);
|
|
StretchBlt(hdcPaint, 5, 5, rcClient.right - 10, rcClient.bottom - 10, hdcBitmap, 0, 0, dwWidth, dwHeight, SRCCOPY);
|
|
|
|
SelectObject(hdcBitmap, hbmOld);
|
|
DeleteDC(hdcBitmap);
|
|
} else if (iv == IV_ALPHA && vd.hbmpAlpha != NULL) {
|
|
HDC hdcBitmap = NULL;
|
|
HBITMAP hbmOld = NULL;
|
|
DWORD dwWidth, dwHeight;
|
|
bool fAlpha;
|
|
|
|
GetBitmapSize(vd, dwWidth, dwHeight, fAlpha);
|
|
|
|
hdcBitmap = CreateCompatibleDC(hdcPaint);
|
|
hbmOld = (HBITMAP) SelectObject(hdcBitmap, vd.hbmpAlpha);
|
|
StretchBlt(hdcPaint, 5, 5, rcClient.right - 10, rcClient.bottom - 10, hdcBitmap, 0, 0, dwWidth, dwHeight, SRCCOPY);
|
|
SelectObject(hdcBitmap, hbmOld);
|
|
DeleteDC(hdcBitmap);
|
|
} else {
|
|
DrawText(hdcPaint, TEXT("No icon data to display"), -1, &rcClient, DT_CENTER | DT_SINGLELINE | DT_VCENTER);
|
|
}
|
|
|
|
if (dop == DO_METAFILEDC) {
|
|
HMETAFILE hMetafile = CloseMetaFile(hdcPaint);
|
|
PlayMetaFile(hdcWindow, hMetafile);
|
|
DeleteMetaFile(hMetafile);
|
|
} else if (dop == DO_ENHMETAFILEDC) {
|
|
HENHMETAFILE hMetafile = CloseEnhMetaFile(hdcPaint);
|
|
PlayEnhMetaFile(hdcWindow, hMetafile, &rcClient);
|
|
DeleteEnhMetaFile(hMetafile);
|
|
} else {
|
|
hdcPaint = NULL;
|
|
}
|
|
|
|
EndPaint(hWnd, &ps);
|
|
}
|
|
break;
|
|
|
|
case WM_SETCURSOR:
|
|
if (LOWORD(lParam) == HTCLIENT) {
|
|
HCURSOR hCursor = NULL;
|
|
|
|
switch (cv) {
|
|
case CV_ICON:
|
|
hCursor = (HCURSOR) vd.hIcon;
|
|
break;
|
|
|
|
case CV_CURSOR:
|
|
hCursor = vd.hIconCursor;
|
|
break;
|
|
|
|
case CV_DEFAULT:
|
|
hCursor = vd.hDefaultCursor;
|
|
break;
|
|
}
|
|
|
|
SetCursor(hCursor);
|
|
return(TRUE);
|
|
} else {
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
ClearViewData(vd);
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
ATOM RegisterLoadIconClass(HINSTANCE hInstance)
|
|
{
|
|
WNDCLASSEX wcex;
|
|
|
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
wcex.lpfnWndProc = WndProc;
|
|
wcex.cbClsExtra = 0;
|
|
wcex.cbWndExtra = 0;
|
|
wcex.hInstance = hInstance;
|
|
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR) IDI_SHOWICON);
|
|
wcex.hCursor = NULL;
|
|
wcex.hbrBackground = NULL;
|
|
wcex.lpszMenuName = (LPCTSTR) IDC_SHOWICON;
|
|
wcex.lpszClassName = TEXT("LoadIconClass");
|
|
wcex.hIconSm = LoadIcon(hInstance, (LPCTSTR) IDI_SHOWICON);
|
|
|
|
return RegisterClassEx(&wcex);
|
|
}
|
|
|
|
int
|
|
WINAPI
|
|
WinMain(
|
|
HINSTANCE hInstance,
|
|
HINSTANCE hPrevInstance,
|
|
LPSTR lpCmdLine,
|
|
int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
HACCEL hAccelTable = LoadAccelerators(hInstance, (LPCTSTR) IDC_SHOWICON);
|
|
LPWSTR *argv;
|
|
int argc;
|
|
|
|
g_hInstance = hInstance;
|
|
|
|
//
|
|
// Register the window class.
|
|
//
|
|
RegisterLoadIconClass(hInstance);
|
|
|
|
HWND hwndMain = CreateWindow(TEXT("LoadIconClass"),
|
|
TEXT("LoadIcon"),
|
|
WS_OVERLAPPEDWINDOW,
|
|
CW_USEDEFAULT,
|
|
0,
|
|
180,
|
|
180,
|
|
NULL,
|
|
NULL,
|
|
hInstance,
|
|
NULL);
|
|
if (hwndMain == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
/*
|
|
* For now we only allow one file to be passed on the command line.
|
|
* Ideally, we should package up the VIEWDATA, LOADOPTIONS, etc. into a
|
|
* struct that we hang off each window. Then we can open a window for every
|
|
* file (however many) on the cl.
|
|
*
|
|
* Moreover, the file can't be on a share; it must be local. I'm not sure if
|
|
* this is by design, but it's something to look into.
|
|
*/
|
|
if (argc == 2) {
|
|
SendMessage(hwndMain, WM_SO_LOADFILE, (WPARAM)0, (LPARAM)argv[1]);
|
|
}
|
|
GlobalFree(argv);
|
|
ShowWindow(hwndMain, nCmdShow);
|
|
|
|
|
|
while (GetMessage(&msg, NULL, 0, 0)) {
|
|
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
return msg.wParam != 0;
|
|
}
|