Tuesday, September 23, 2008
Saturday, September 20, 2008
Change MSI to run under custom actions under user account
MSI package generated by VS2008 will run custom actions under SYSTEM account. This "feature" was implemented to work around Vista's UAC.
There is no way to change this behavior from VS2008, but you can adjust MSI package using ORCA tool (available in SDK).
Start ORCA tool, open MSI package, navigate to custom actions. Select action which you would like to run under user account and subtract 0x800 from Type. In my case, value generated by VS2008 is 3090, new value should be 1042.
Save MSI back. Done
There is no way to change this behavior from VS2008, but you can adjust MSI package using ORCA tool (available in SDK).
Start ORCA tool, open MSI package, navigate to custom actions. Select action which you would like to run under user account and subtract 0x800 from Type. In my case, value generated by VS2008 is 3090, new value should be 1042.
Save MSI back. Done
Saturday, September 13, 2008
Problem with 0.9.1031 and Silverlight1.0
0.9.1031 crashes when running with SL1.0. SL2.0 Beta2 works fine. If you run into this problem, you can either install SL1.0 or use MyDock0.9.1027
Tuesday, September 9, 2008
Monday, September 1, 2008
SL path mini language to geometry converter
Added utility to http://alexezh.googlepages.com/developlemtinsilverlight to convert Silverlight path mini language to geometry
Sunday, August 31, 2008
pathgeometry vs mini language
http://www.farseergames.com/blog/post/Workaround-for-Accessing-PathGeometry-Data-in-Code.aspx
Sunday, August 24, 2008
using selectSingleNode for XAML
When using selectSingleNode to search XAML, it is required to set SelectionNamespace property with fake prefix. Here is an example
spDoc2->setProperty(CComBSTR(L"SelectionLanguage"), CComVariant(L"XPath"));
spDoc2->setProperty(CComBSTR(L"SelectionNamespaces"),
CComVariant("xmlns:d=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\""));
m_spDoc->selectSingleNode(CComBSTR(L"./d:Canvas"), &m_spRoot);
spDoc2->setProperty(CComBSTR(L"SelectionLanguage"), CComVariant(L"XPath"));
spDoc2->setProperty(CComBSTR(L"SelectionNamespaces"),
CComVariant("xmlns:d=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\""));
m_spDoc->selectSingleNode(CComBSTR(L"./d:Canvas"), &m_spRoot);
Thursday, July 24, 2008
Tuesday, July 22, 2008
MyDock 0.9.1027
New Features
* Added multimonitor support (first version, no configuration UI yet)
o To switch to the second monitor, add1 to dock.xml and restart the dock.
Fixes
* Fixed refresh problem after screen resolution change
* Fixed memory leak (time will tell if this is the last one)
* Added delay for showing dock when new window is activated
* Fixed problem with context menus showing behind dock
* Updated visual for window manager dock
* Add hover indicator to tray menu
* Added multimonitor support (first version, no configuration UI yet)
o To switch to the second monitor, add
Fixes
* Fixed refresh problem after screen resolution change
* Fixed memory leak (time will tell if this is the last one)
* Added delay for showing dock when new window is activated
* Fixed problem with context menus showing behind dock
* Updated visual for window manager dock
* Add hover indicator to tray menu
Monday, July 21, 2008
WebGadgets
After playing with Google desktop gadgets for a while, I decided to implement support for Web gadgets first. Much easier to do plus covers 90% of interesting functionality.
Yesterday got the first result; google clock is running on dashboard. Well, almost running, gadget size is wrong.
Yesterday got the first result; google clock is running on dashboard. Well, almost running, gadget size is wrong.
Tuesday, July 15, 2008
MyDock 0.9.1025
Lot's of updates and bug fixes.
Lately I am spending most of the time on implementing OSX style dashboard and support for google gadgets. Google or Vista sidebars take too much space on screen and provide constant distraction. Old style windows active desktop provides similar functionality, but it requires hiding all apps (which seems like a destructive action).
Last week mydock dashboard displayed the first picture. To be continued.
Lately I am spending most of the time on implementing OSX style dashboard and support for google gadgets. Google or Vista sidebars take too much space on screen and provide constant distraction. Old style windows active desktop provides similar functionality, but it requires hiding all apps (which seems like a destructive action).
Last week mydock dashboard displayed the first picture. To be continued.
Sunday, May 11, 2008
MyDock 0.9.1009
Just posted the latest version of mydock to www.codeplex.com/mydock. The main new feature is limited support for system tray.
Saturday, April 19, 2008
open explorer at My Computer folder
ShellExecute(NULL,
L"explore",
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
NULL,
NULL,
SW_SHOW);
L"explore",
L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}",
NULL,
NULL,
SW_SHOW);
Sunday, April 13, 2008
MyDock 0.9.1001
New release is available here. Main changes are
* Added quit button
* Use high-quality icons if available
* Bug fixes
* Added quit button
* Use high-quality icons if available
* Bug fixes
Friday, April 11, 2008
Migrating dev related items to codeplex
Created a project for tracking items and releases on CodePlex. See MyDock On CodePlex for more details
Saturday, April 5, 2008
XMLDOM tricks
Add \r\n to the document when saving. Original info from Line breaks and IXMLDOMDocument
static LPCWSTR s_szFormatConfig = L""\
L" edit window is not XML friendly, see original post for details";
static HRESULT FormatConfig(IXMLDOMDocument * pInDoc, CComPtr & spOutDoc)
{
HRESULT hr = S_OK;
CComPtr spSS;
VARIANT_BOOL vbSuccess;
IFC(CoCreateInstance(__uuidof(DOMDocument60),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&spSS));
IFC(CoCreateInstance(__uuidof(DOMDocument60),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&spOutDoc));
spSS->put_resolveExternals(VARIANT_FALSE);
spSS->put_preserveWhiteSpace(VARIANT_TRUE);
spOutDoc->put_resolveExternals(VARIANT_FALSE);
spOutDoc->put_preserveWhiteSpace(VARIANT_TRUE);
//
// load SS from string
//
IFC(spSS->loadXML(CComBSTR(s_szFormatConfig), &vbSuccess));
if(vbSuccess != VARIANT_TRUE)
{
hr = E_FAIL;
goto Cleanup;
}
//
// convert
//
IFC(pInDoc->transformNodeToObject(spSS, CComVariant(spOutDoc)));
Cleanup:
return hr;
}
Convert document to UTF8
static HRESULT ForceUTF8(IXMLDOMDocument * pDoc)
{
HRESULT hr = S_OK;
CComPtr spPI;
CComPtr spOldPI;
CComPtr spOutOldPI;
CComPtr spChildren;
IFC(pDoc->createProcessingInstruction(L"xml", L"version=\"1.0\" encoding=\"UTF-8\"", &spPI));
IFC(pDoc->get_childNodes(&spChildren));
IFC(spChildren->get_item(0, &spOldPI));
IFC(pDoc->replaceChild( spPI, spOldPI, &spOutOldPI));
Cleanup:
return hr;
}
static LPCWSTR s_szFormatConfig = L""\
L" edit window is not XML friendly, see original post for details";
static HRESULT FormatConfig(IXMLDOMDocument * pInDoc, CComPtr
{
HRESULT hr = S_OK;
CComPtr
VARIANT_BOOL vbSuccess;
IFC(CoCreateInstance(__uuidof(DOMDocument60),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&spSS));
IFC(CoCreateInstance(__uuidof(DOMDocument60),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&spOutDoc));
spSS->put_resolveExternals(VARIANT_FALSE);
spSS->put_preserveWhiteSpace(VARIANT_TRUE);
spOutDoc->put_resolveExternals(VARIANT_FALSE);
spOutDoc->put_preserveWhiteSpace(VARIANT_TRUE);
//
// load SS from string
//
IFC(spSS->loadXML(CComBSTR(s_szFormatConfig), &vbSuccess));
if(vbSuccess != VARIANT_TRUE)
{
hr = E_FAIL;
goto Cleanup;
}
//
// convert
//
IFC(pInDoc->transformNodeToObject(spSS, CComVariant(spOutDoc)));
Cleanup:
return hr;
}
Convert document to UTF8
static HRESULT ForceUTF8(IXMLDOMDocument * pDoc)
{
HRESULT hr = S_OK;
CComPtr
CComPtr
CComPtr
CComPtr
IFC(pDoc->createProcessingInstruction(L"xml", L"version=\"1.0\" encoding=\"UTF-8\"", &spPI));
IFC(pDoc->get_childNodes(&spChildren));
IFC(spChildren->get_item(0, &spOldPI));
IFC(pDoc->replaceChild( spPI, spOldPI, &spOutOldPI));
Cleanup:
return hr;
}
Friday, April 4, 2008
MyDock, 04-03-2007
Added window manager docklet. Window manager allow you to perform common operations on active window such as resize to half of screen, move to different monitor etc
Wednesday, April 2, 2008
TODO list
Some ideas for todo list
- OSX type Dashboard with SL2.0 applets
- Windows manager similar to vMax (in progress)
- Search box (similar to search in the start menu on Vista)
- Run docklet
- Hide windows taskbar
- Tray docklet
- Run as admin option
- OSX type Dashboard with SL2.0 applets
- Windows manager similar to vMax (in progress)
- Search box (similar to search in the start menu on Vista)
- Run docklet
- Hide windows taskbar
- Tray docklet
- Run as admin option
Monday, March 31, 2008
MyDock, bug fixes
Minor bug fixes
- fix AV when closing application
- fix duplicated icons when starting mydock
Download from MyDock032107_1.zip
- fix AV when closing application
- fix duplicated icons when starting mydock
Download from MyDock032107_1.zip
Number of updates
- Added initial version of drag&drop support both from shell and inside the dock. Now you can re-arrange docklets by dragging them
- Added configuration file for basic properties like docklet size. See dock_mini.xml for details. To use configuration, rename dock_mini.xml to dock.xml and copy it to either application directory or appdata directory
- Added key to hide / show the dock. Configurable through global config
As usual, download from
MyDock033107
- Added initial version of drag&drop support both from shell and inside the dock. Now you can re-arrange docklets by dragging them
- Added configuration file for basic properties like docklet size. See dock_mini.xml for details. To use configuration, rename dock_mini.xml to dock.xml and copy it to either application directory or appdata directory
- Added key to hide / show the dock. Configurable through global config
As usual, download from
MyDock033107
Wednesday, March 26, 2008
Tuesday, March 25, 2008
mydock, 03-25-2007
My clone of OS X dock. Requires SilverLight runtime to run.
I've been using ObjectDock for a while, but was always disappointed by lack of functionality compared to OS X dock.
Main difference is in the way how applications are handled by the dock. In OS X, same icon can be used to started pinned application or switch to it. If application is not pinned, clicking on icon activates the application. In ObjectDock, there are two types of icons; one for running windows and second for pinned apps. As a result, you might see two instances of the same icon.
To try mydock,
- download MyDock.zip unzip it to an empty folder
- run "mydock.exe".
- md5 hash for zip file is 3e57f216ce78920952207b34502d236e
Code is under active development. To be continued....
I've been using ObjectDock for a while, but was always disappointed by lack of functionality compared to OS X dock.
Main difference is in the way how applications are handled by the dock. In OS X, same icon can be used to started pinned application or switch to it. If application is not pinned, clicking on icon activates the application. In ObjectDock, there are two types of icons; one for running windows and second for pinned apps. As a result, you might see two instances of the same icon.
To try mydock,
- download MyDock.zip unzip it to an empty folder
- run "mydock.exe".
- md5 hash for zip file is 3e57f216ce78920952207b34502d236e
Code is under active development. To be continued....
extract icon from exe
Code based on http://msdn2.microsoft.com/en-us/library/ms997538.aspx.
class CIconExtractor
{
public:
CIconExtractor()
: m_pImage(NULL)
{
}
HRESULT LoadIconFromApp(LPCWSTR pszFileName, CPngImage ** ppImage);
private:
CPngImage * m_pImage;
private:
static BOOL CALLBACK EnumIconProcInit(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName,
LONG_PTR lParam);
BOOL EnumIconProc(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName);
HRESULT GetResourceBytes(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, CAtlArray & arRes);
HRESULT LoadIconFromGroup(HMODULE hModule, CAtlArray & arRes);
};
///////////////////////////////////////////////////////////////////////////////
//
HRESULT CIconExtractor::LoadIconFromApp(LPCWSTR pszFileName, CPngImage ** ppImage)
{
HRESULT hr = S_OK;
HMODULE hExe; // handle to existing .EXE file
BOOL bRet;
// Load the .EXE file that contains an icon.
hExe = LoadLibraryEx(pszFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (hExe == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
bRet = EnumResourceNames(hExe, RT_GROUP_ICON, EnumIconProcInit, (LONG_PTR)(void*)this);
if(!m_pImage)
{
if(!bRet)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
hr = E_FAIL;
}
goto Cleanup;
}
*ppImage = m_pImage;
m_pImage = NULL;
Cleanup:
// Clean up.
if(hExe)
{
FreeLibrary(hExe);
}
if(m_pImage)
{
delete m_pImage;
m_pImage = NULL;
}
return hr;
}
BOOL CALLBACK CIconExtractor::EnumIconProcInit(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName,
LONG_PTR lParam)
{
CIconExtractor * pThis = (CIconExtractor*)lParam;
return pThis->EnumIconProc(hModule, lpszType, lpszName);
}
BOOL CIconExtractor::EnumIconProc(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName)
{
HRESULT hr = S_OK;
CAtlArray arResGroup;
IFC(GetResourceBytes(hModule, lpszType, lpszName, arResGroup));
IFC(LoadIconFromGroup(hModule, arResGroup));
Cleanup:
SetLastError(NO_ERROR);
return FALSE;
}
HRESULT CIconExtractor::GetResourceBytes(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, CAtlArray & arRes)
{
HRESULT hr = S_OK;
HGLOBAL hResLoad; // handle to loaded resource
HRSRC hRes; // handle/ptr. to res. info. in hExe
HANDLE hUpdateRes; // update resource handle
void *pbRes; // pointer to resource data
DWORD cbRes;
// Locate the icon resource in the .EXE file.
hRes = FindResource(hModule, lpszName, lpszType);
if (hRes == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
// Load the icon
hResLoad = LoadResource(hModule, hRes);
if (hResLoad == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
cbRes = SizeofResource(hModule, hRes);
// Lock the dialog box into global memory.
pbRes = LockResource(hResLoad);
if (pbRes == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
arRes.SetCount(cbRes);
CopyMemory(arRes.GetData(), pbRes, cbRes);
Cleanup:
return hr;
}
// descriptor for the icon group
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
WORD nID; // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
typedef struct
{
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource type (1 for icons)
WORD idCount; // How many images?
GRPICONDIRENTRY idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
DWORD dwBytesOffset; // the ID
} ICONHEADER, *LPICONHEADER;
#pragma pack( pop )
HRESULT CIconExtractor::LoadIconFromGroup(HMODULE hModule, CAtlArray & arRes)
{
HRESULT hr = S_OK;
GRPICONDIR * pDir;
WORD i;
GRPICONDIRENTRY * pCur = NULL;
GRPICONDIRENTRY * pBest = NULL;
CAtlArray arIcon;
HICON hIcon = NULL;
if(arRes.GetCount() < sizeof(GRPICONDIR))
{
hr = E_FAIL;
goto Cleanup;
}
pDir = (GRPICONDIR *)(void*)arRes.GetData();
if(pDir->idCount < 1 || arRes.GetCount() < sizeof(GRPICONDIR) + (pDir->idCount - 1) * sizeof(GRPICONDIRENTRY))
{
hr = E_FAIL;
goto Cleanup;
}
//
// find best icon
//
pCur = pBest = &pDir->idEntries[0];
for(i = 0; i < pDir->idCount; i++)
{
pCur = &pDir->idEntries[i];
if(pCur->wBitCount > pBest->wBitCount)
{
pBest = pCur;
}
else if(pCur->bWidth > pBest->bWidth)
{
pBest = pCur;
}
}
//
// load best icon
//
IFC(GetResourceBytes(hModule, RT_ICON, MAKEINTRESOURCE(pBest->nID), arIcon));
hIcon = CreateIconFromResource(arIcon.GetData(), arIcon.GetCount(), TRUE, 0x00030000);
if(!hIcon)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
{
CMyImage WndImage;
if(pBest->wBitCount == 0x20)
{
CMyIcon::Load(arIcon.GetData(), arIcon.GetCount(), WndImage);
}
else
{
CIconToImageConverter cnv;
IFC(cnv.GetImage(hIcon, WndImage));
goto Cleanup;
}
m_pImage = new CPngImage;
if(m_pImage == NULL)
{
goto Cleanup;
}
m_pImage->Encode(WndImage);
}
Cleanup:
if(hIcon)
{
DestroyIcon(hIcon);
}
return hr;
}
class CIconExtractor
{
public:
CIconExtractor()
: m_pImage(NULL)
{
}
HRESULT LoadIconFromApp(LPCWSTR pszFileName, CPngImage ** ppImage);
private:
CPngImage * m_pImage;
private:
static BOOL CALLBACK EnumIconProcInit(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName,
LONG_PTR lParam);
BOOL EnumIconProc(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName);
HRESULT GetResourceBytes(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, CAtlArray
HRESULT LoadIconFromGroup(HMODULE hModule, CAtlArray
};
///////////////////////////////////////////////////////////////////////////////
//
HRESULT CIconExtractor::LoadIconFromApp(LPCWSTR pszFileName, CPngImage ** ppImage)
{
HRESULT hr = S_OK;
HMODULE hExe; // handle to existing .EXE file
BOOL bRet;
// Load the .EXE file that contains an icon.
hExe = LoadLibraryEx(pszFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
if (hExe == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
bRet = EnumResourceNames(hExe, RT_GROUP_ICON, EnumIconProcInit, (LONG_PTR)(void*)this);
if(!m_pImage)
{
if(!bRet)
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
hr = E_FAIL;
}
goto Cleanup;
}
*ppImage = m_pImage;
m_pImage = NULL;
Cleanup:
// Clean up.
if(hExe)
{
FreeLibrary(hExe);
}
if(m_pImage)
{
delete m_pImage;
m_pImage = NULL;
}
return hr;
}
BOOL CALLBACK CIconExtractor::EnumIconProcInit(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName,
LONG_PTR lParam)
{
CIconExtractor * pThis = (CIconExtractor*)lParam;
return pThis->EnumIconProc(hModule, lpszType, lpszName);
}
BOOL CIconExtractor::EnumIconProc(
HMODULE hModule,
LPCTSTR lpszType,
LPTSTR lpszName)
{
HRESULT hr = S_OK;
CAtlArray
IFC(GetResourceBytes(hModule, lpszType, lpszName, arResGroup));
IFC(LoadIconFromGroup(hModule, arResGroup));
Cleanup:
SetLastError(NO_ERROR);
return FALSE;
}
HRESULT CIconExtractor::GetResourceBytes(HMODULE hModule, LPCTSTR lpszType, LPTSTR lpszName, CAtlArray
{
HRESULT hr = S_OK;
HGLOBAL hResLoad; // handle to loaded resource
HRSRC hRes; // handle/ptr. to res. info. in hExe
HANDLE hUpdateRes; // update resource handle
void *pbRes; // pointer to resource data
DWORD cbRes;
// Locate the icon resource in the .EXE file.
hRes = FindResource(hModule, lpszName, lpszType);
if (hRes == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
// Load the icon
hResLoad = LoadResource(hModule, hRes);
if (hResLoad == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
cbRes = SizeofResource(hModule, hRes);
// Lock the dialog box into global memory.
pbRes = LockResource(hResLoad);
if (pbRes == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
arRes.SetCount(cbRes);
CopyMemory(arRes.GetData(), pbRes, cbRes);
Cleanup:
return hr;
}
// descriptor for the icon group
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
WORD nID; // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
typedef struct
{
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource type (1 for icons)
WORD idCount; // How many images?
GRPICONDIRENTRY idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
DWORD dwBytesOffset; // the ID
} ICONHEADER, *LPICONHEADER;
#pragma pack( pop )
HRESULT CIconExtractor::LoadIconFromGroup(HMODULE hModule, CAtlArray
{
HRESULT hr = S_OK;
GRPICONDIR * pDir;
WORD i;
GRPICONDIRENTRY * pCur = NULL;
GRPICONDIRENTRY * pBest = NULL;
CAtlArray
HICON hIcon = NULL;
if(arRes.GetCount() < sizeof(GRPICONDIR))
{
hr = E_FAIL;
goto Cleanup;
}
pDir = (GRPICONDIR *)(void*)arRes.GetData();
if(pDir->idCount < 1 || arRes.GetCount() < sizeof(GRPICONDIR) + (pDir->idCount - 1) * sizeof(GRPICONDIRENTRY))
{
hr = E_FAIL;
goto Cleanup;
}
//
// find best icon
//
pCur = pBest = &pDir->idEntries[0];
for(i = 0; i < pDir->idCount; i++)
{
pCur = &pDir->idEntries[i];
if(pCur->wBitCount > pBest->wBitCount)
{
pBest = pCur;
}
else if(pCur->bWidth > pBest->bWidth)
{
pBest = pCur;
}
}
//
// load best icon
//
IFC(GetResourceBytes(hModule, RT_ICON, MAKEINTRESOURCE(pBest->nID), arIcon));
hIcon = CreateIconFromResource(arIcon.GetData(), arIcon.GetCount(), TRUE, 0x00030000);
if(!hIcon)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Cleanup;
}
{
CMyImage WndImage;
if(pBest->wBitCount == 0x20)
{
CMyIcon::Load(arIcon.GetData(), arIcon.GetCount(), WndImage);
}
else
{
CIconToImageConverter cnv;
IFC(cnv.GetImage(hIcon, WndImage));
goto Cleanup;
}
m_pImage = new CPngImage;
if(m_pImage == NULL)
{
goto Cleanup;
}
m_pImage->Encode(WndImage);
}
Cleanup:
if(hIcon)
{
DestroyIcon(hIcon);
}
return hr;
}
Sunday, March 23, 2008
find location of installed application by app name
HRESULT hr = S_OK;
CComPtr spDocklet;
CRegKey rkAppPaths;
CRegKey rkApp;
WCHAR szPath[MAX_PATH];
ULONG cchPath;
CAtlString szAppPath;
LONG lRes;
lRes = rkAppPaths.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths", KEY_READ);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
lRes = rkApp.Open(rkAppPaths, pszApp);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
cchPath = sizeof(szPath) / sizeof(WCHAR);
lRes = rkApp.QueryStringValue(L"Path", szPath, &cchPath);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
szAppPath.Format(L"%s%s", szPath, pszApp);
CComPtr
CRegKey rkAppPaths;
CRegKey rkApp;
WCHAR szPath[MAX_PATH];
ULONG cchPath;
CAtlString szAppPath;
LONG lRes;
lRes = rkAppPaths.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths", KEY_READ);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
lRes = rkApp.Open(rkAppPaths, pszApp);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
cchPath = sizeof(szPath) / sizeof(WCHAR);
lRes = rkApp.QueryStringValue(L"Path", szPath, &cchPath);
if(lRes != ERROR_SUCCESS)
{
goto Cleanup;
}
szAppPath.Format(L"%s%s", szPath, pszApp);
Tuesday, March 18, 2008
Subscribe to:
Posts (Atom)