Where, in Windows, is this icon stored? I need to use it in a TaskDialog emulation for XP and am having a hard time tracking it down.
It's not in shell32.dll, explorer.exe, ieframe.dll or wmploc.dll (as these contain a lot of icons commonly used in Windows).
Edit:
For clarification, I am emulating a certain type of dialog in XP. The icon is (most likely) not present there. So I want to extract it from the library that holds it in Windows 7. I am extending an existing implementation of this emulation and want to provide a full feature set.
I wanted to point it out explicitly.
You are supposed to put a shield on UI elements that will trigger an elevation: MSDN: Step 4: Redesign Your UI for UAC Compatibility.
Of course, you don't have to go spelunking around DLLs to extract images (although it certainly does make it easier at design time when you can design your design with a design time interface).
Microsoft provides a couple of supported (and therefore guaranteed) ways that you can get ahold of the shield icon at runtime:
Add a shield icon to the user interface?:
Extract a small icon
SHSTOCKICONINFO sii;
sii.cbSize = sizeof(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_SMALLICON, &sii);
hiconShield = sii.hIcon;
Extract a large icon
SHSTOCKICONINFO sii;
sii.cbSize = sizeof(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICON | SHGSI_LARGEICON, &sii);
hiconShield = sii.hIcon;
Extract an icon of custom size
SHSTOCKICONINFO sii;
sii.cbSize = sizeof(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, &sii);
hiconShield = ExtractIconEx(sii. ...);
Add a Shield Icon to a Button
Button_SetElevationRequiredState(hwndButton, TRUE);
The article forgot to mention LoadIcon:
hIconShield = LoadIcon(0, IDI_SHIELD);
Although LoadIcon has been "superseded" by LoadImage:
hIconShield = LoadImage(0, IDI_SHIELD, IMAGE_ICON, desiredWith, desiredHeight, LR_SHARED); //passing LR_SHARED causes size to be ignored. And you must pass LR_SHARED
Loading the size you want - by avoiding shared images
In order to avoid loading a "shared" version of the icon, you have to load the icon directly out of the file.
We all know that the shield exists in user32.dll as resource id 106:
| Icon | Standard Icon ID | Real Resource ID |
|------------------|-------------------|------------------|
| IDI_APPLICATION | 32512 | 100 |
| IDI_QUESTION | 32514 | 102 |
| IDI_WINLOGO | 32517 | 105 |
| IDI_WARNING | 32515 | 101 |
| IDI_ERROR | 32513 | 103 |
| IDI_INFORMATION | 32516 | 104 |
| IDI_SHIELD | 32518 | 106 |
That was undocumented spellunking.
SHGetStockIconInfo can give us the actual, current, guaranteed to change in the future, path and index:
TSHStockIconInfo sii;
ZeroMemory(#sii, SizeOf(sii));
sii.cbSize := SizeOf(sii);
SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);
resulting in:
sii.szPath: C:\WINDOWS\System32\imageres.dll
sii.iIcon: -78
You can load this image for the size you desire using LoadImage:
HMODULE hmod := LoadLibrary(sii.szPath);
Integer nIconIndex := Abs(sii.iIcon); //-78 --> 78
ico = LoadImage(hmod, MAKEINTRESOURCE(nIconIndex), IMAGE_ICON, 256, 256, 0);
Another slightly easier way is to use SHDefExtractIcon:
HICON GetStockIcon(DWORD StockIconID, Integer IconSize)
{
HRESULT hr;
TSHStockIconInfo sii;
ZeroMemory(#sii, SizeOf(sii));
sii.cbSize := SizeOf(sii);
hr = SHGetStockIconInfo(SIID_SHIELD, SHGSI_ICONLOCATION, {var}sii);
OleCheck(hr);
HICON ico;
hr = SHDefExtractIcon(sii.szPath, sii.iIcon, 0, ref ico, null, IconSize);
OleCheck(hr);
return ico;
}
It does the loading for you, and it handles the negative icon index (and the secret meaning that has):
HICON shieldIcon = GetStockIcon(SIID_SHIELD, 256);
Personally, i then use WIC to wrap that into a IWICBitmap:
IWICBitmap GetStockWicBitmap(DWORD StockIconID, Integer IconSize)
{
HICON ico = GetStockIcon(StockIconID, IconSize);
IWICBitmap bitmap;
IWICImagingFactory factory = new WICImagingFactory();
HRESULT hr = factory.CreateBitmapFromHICON(ico, out bitmap);
OleCheck(hr);
return bitmap;
}
and so:
IWICBitmap bmp = GetStockWicBitmap(SIID_SHIELD, 256);
Now that you have the bitmap, at runtime, do with it what you want.
Small and Large
The problem with ExtractIconEx is that you're again stuck with the two shell sizes:
"small" (i.e. GetSystemMetrics(SM_CXSMICON))
"large" (i.e. GetSystemMetrics(SM_CXICON))
Loading icons is something that is quite a dark art in Windows:
LoadIcon
LoadImage
LoadImage(..., LR_SHARED)
ExtractIcon
ExtractIconEx
IExtractImage
SHDefExtractIcon
SHGetFileInfo(..., SHGFI_ICON, ...);
SHGetFileInfo(..., SHGFI_SYSICONINDEX, ...);
SHGetFileInfo(..., SHGFI_ICONLOCATION, ...);
IThumbnailProvider
Icons available through SHGetStockIconInfo
Microsoft gives a handy page that gives an example, and description, of all the stock icons.
SHSTOCKICONID (archive)
And the 256px shield icon (as of Windows 10):
The shield icon is located in the file C:\Windows\System32\imageres.dll (at least, in my copy of English 32-bit Windows 7). There are several versions of the shield icon there, including the blue and yellow version you have above (icon 78).
Icons extracted from Windows 7 x64 SP1 English:
16x16 shield icon:
24x24 shield icon:
32x32 shield icon:
You are asking the wrong question. It doesn't matter where this icon is stored on any version of windows. If Microsoft don't tell you then you should not use it - it might not be there in windows 8 (or whatever comes after 7).
If you want the icon so bad, there is a decent graphical representation of it above in this question. You could do alt-prt scrn then use your favourite graphics app to turn it into an icon and add it to your app. This may not be legal though (remember, IANAL)
Related
On Windows 10 calling LoadIcon asking for the standard icon IDI_INFORMATION yields this icon:
On the other hand, calling MessageBox passing IDI_INFORMATION produces a dialog that uses this icon:
How can I obtain the second icon, if the obvious call to LoadIcon does not do so?
This feels like a bug in user32.dll but Windows 8 has the same issue so I guess Microsoft doesn't care.
You can get the flat icon used by MessageBox by calling SHGetStockIconInfo:
SHSTOCKICONINFO sii;
sii.cbSize = sizeof(sii);
if (SUCCEEDED(SHGetStockIconInfo(SIID_INFO, SHGSI_ICON|SHGSI_LARGEICON, &sii)))
{
// Use sii.hIcon here...
DestroyIcon(sii.hIcon);
}
SHGetStockIconInfo is the documented way to get icons used in the Windows UI on Vista and later. Most of the icons come from imageres.dll but you should not assume that this is the case...
we can try next code for test/demo
MSGBOXPARAMSW mbi = {
sizeof(mbi),
HWND_DESKTOP,
NULL,
L"lpszText",
L"lpszCaption",
MB_USERICON,
IDI_INFORMATION
};
MessageBoxIndirectW(&mbi);
if (HMODULE hmodImageRes = LoadLibraryEx(L"imageres", 0, LOAD_LIBRARY_AS_DATAFILE))
{
mbi.hInstance = hmodImageRes;
mbi.lpszIcon = MAKEINTRESOURCE(81);
MessageBoxIndirectW(&mbi);
FreeLibrary(hmodImageRes);
}
first message box use standard IDI_INFORMATION icon
when second the same icon on windows 7, and on windows 8.1 and windows 10.
are MAKEINTRESOURCE(81) from imageres.dll somehow documented and be stable - i doubt
so obtain the second icon you can by LoadIcon(hmodImageRes, MAKEINTRESOURCE(81)) where HMODULE hmodImageRes = LoadLibraryEx(L"imageres", 0, LOAD_LIBRARY_AS_DATAFILE) or simply LoadLibrary(L"imageres")
In Windows, it is possible to say
CreateWindow("myclass",...,WS_CHILD,...);
or
CreateWindow("myclass",...,WS_OVERLAPPEDWINDOW,...);
It is also possible to switch appearance at will:
SetWindowLongPtr((HWND)handle,GWL_STYLE,style_1);
SetWindowPos((HWND)handle,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
SetWindowLongPtr((HWND)handle,GWL_EXSTYLE,style_0);
SetWindowPos((HWND)handle,HWND_TOP,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
if(style_1&WS_CHILD)
{
HWND owner=GetWindow((HWND)handle,GW_OWNER);
SetParent((HWND)handle,owner);
}
else
{SetParent((HWND)handle,NULL);}
It seems to me that most other GUI toolkits make a clear distinction between top-level windows and other widgets. The question is if and how it is possible to implement similar behavior in GTK on X
There is a GTK_WINDOW_TOPLEVEL and GTK_WINDOW_POPUP - unless you know what you do use the first. Also RTM https://developer.gnome.org/gtk3/stable/gtk3-Standard-Enumerations.html#GtkWindowType
You need to create a GtkWindow or GtkMainWindow and then add your desired widget x via gtk_container_add to the window you created.
We have a piece of software that is programmed against DirextX 7 SDK (i.e the code uses LPDIRECTDRAWSURFACE7 and the likes) and runs in fullscreen. The main task is putting something on the screen in response to external triggers in a reliable manner. This behaves very well on Windows XP: bsically the software waits for some trigger and when triggered, creates a new frame, puts it in the backbuffer, then tells DX to flip the buffers. The result is the approximate delay between the trigger and when the frame is effectively shown on the screen is, depending on video card and drivers, 3 frames or 50mSec for a 60Hz screen. This is tested on a variety of systems, all running NVidia cards. On some systems with higher end cards we even get 2 frames.
When running the same software on Windows 7 (with no other software installed at all) however, we cannot get lower than 5 frames. Meaning somewhere in the pipeline the OS or driver or both eat 2 extra frames, which is near to unacceptable for the application. We tried disabling aero/desktop composition/different driver versions/different video cards but no avail.
where does this come from? is this documented somewhere?
is there an easy way to fix? I know DirectX 7 is old, but upgrading to compile agains a more recent version might be tons of work so another type of fix would be nice. Maybe some flag that can be set in code?
edit here's some code which seems relevant:
Creation of front/back surfaces:
ddraw7->SetCooperativeLevel( GetSafeHwnd(),
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED )
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof( desc );
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE |
DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
desc.dwBackBufferCount = 1;
ddraw7->CreateSurface( &desc, &primsurf, 0 )
DDSCAPS2 surfcaps;
ZeroMemory( &surfcaps,sizeof( surfcaps ) );
surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
primsurf->GetAttachedSurface( &surfcaps, &backsurf );
Creation of surfaces used to render frames before they get drawn:
DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
desc.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
LPDIRECTDRAWSURFACE7 surf;
HRESULT r=ddraw7->CreateSurface( &desc, &surf, 0 )
Rendering loop, in OnIdle:
//clear surface
DDBLTFX bltfx;
ZeroMemory( &bltfx, sizeof(bltfx) );
bltfx.dwSize = sizeof( bltfx );
bltfx.dwFillColor = RGBtoPixel( r, g, b );
backsurf->Blt( rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx )
//blit some prerendered surface onto it, x/y/rect etc are calculated properly)
backsurf->BltFast( x, y, sourceSurf, s&sourceRect, DDBLTFAST_WAIT );
primsurf->Flip( 0, DDFLIP_WAIT )
primsurf->Blt(&drect,backsurf,&srect,DDBLT_WAIT,0);
I think that the Windows XP thing is a red herring. The last version of Windows that ran DirectX 7 directly was Windows 2000. Windows XP is just emulating DX7 in DX9, same as Windows 7 is doing.
I'll venture a guess that your application uses palettized textures, and that when DX emulates that functionality (as it was dropped after DX7) it's generating a texture using the indexed colors. You might try profiling the app with GPUView to see if there's a delay in pushing the texture to the GPU. E.g., perhaps the Win7 driver compressing it first?
I am trying to add Image before the text in CTreeList control but it is not coming up, But what i observed is the the node name is started after some space , like it is leaving the space for bitmap , but image is not showing up.. here is the code snap:-
CImageList m_ImageList;
CBitmap m_Bitmap1;
m_ImageList.Create(16,16,ILC_COLOR32,1,1);
m_Bitmap1.LoadBitmap(IDB_BITMAP1);
m_ImageList.Add(&m_Bitmap1, RGB(0,0,0));
TreeSoft->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP |
TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT |
TVS_SINGLEEXPAND | TVS_SHOWSELALWAYS |
TVS_TRACKSELECT,
CRect(10, 10, 200, 240), this, 0x1221);
TreeSoft->SetImageList(&m_ImageList, TVSIL_NORMAL);
hTree = TreeSoft->InsertItem( L"Software Production",0,0, TVI_ROOT);
hCompany = TreeSoft->InsertItem(L"Microsoft",0,0, hTree);
Pls tell me what i am missing here...
Now you just need to set the image for the newly created branch:
TreeSoft->SetItemImage(hTree , 0, 0); // I think it starts from 0 (if it does not show try 1)
Just for testing purposes.
Create an icon with 16-bit color palette.
Instead of ILC_COLOR32 use ILC_COLOR.
And instead of RGB(0,0,0) use (COLORREF)0xFFFFFF
I have exact the same code except the smaller color palette and it works.
If this works you can try with the bigger palette.
I am trying to use some classes from the MFC Feature Pack to improve the look & feel of my MFC application.
In my application, I use one CReBar object to dock three different toolbars. I have updated the class of this object to use CMFCReBar, but it doesn´t look good when using some visual styles.
It seems there's a problem in the Feature Pack because it happens even with the RebarTest example deployed with package.
This is a screenshot of the example application just changing the visual style to Office 2007 (using the app. menu not by code):
Screenshot of RebarTest example application http://img105.imageshack.us/img105/1057/rebartestep5.png
Has anybody successfully used CMFCReBar? Is there any other way to achieve the same without using it?
Basically you don't need to use a rebar control anymore. By simply creating your CMFCToolbars and CMFCMenuBar, calling EnableDocking on them and then using DockPane on each, they will dock and take on the Office 2007 (or whatever other theme you use) look-and-feel. Check out the WordPad Feature Pack sample, or create a new project (one with all the default settings is fine) using AppWizard to see an example.
Ok from your comment: if you want to dock toolbars next to each other you can use DockPaneLeftOf after DockPane. It tends to act strangely with toolbar placement in my experience if you don't DockPane both toolbars first.
I haven't found a good simple solution to stopping the toolbars from being dragged yet while docking next to each other, you can remove the CBRS_GRIPPER style, however that doesn't stop the toolbars from being dragged.
You can also just not call EnableDocking on the menubar or toolbars. This will make them fixed place. However, DockPaneLeftOf does not seem to work in this case, so you lose docking toolbars next to each other.
So it seems like one or the other right now if you want to stop docking, or dock toolbars next to each other.
Paul DiLascia wrote a class to lock the CToolBar, I used it to create this class which will work on CMFCToolbar. And you can copy it to do exactly the same sort of thing for CMFCMenuBar - just change MFCToolBar to MFCMenuBar and you're done.
class CLockedMFCToolBar : public CMFCToolBar
{
public:
CLockedMFCToolBar() : CMFCToolBar() {}
protected:
LRESULT CLockedMFCToolBar::WindowProc(UINT msg, WPARAM wp, LPARAM lp)
{
if ((msg==WM_LBUTTONDOWN || msg==WM_LBUTTONDBLCLK))
{
// Got click or double-click and toolbar is locked: if mouse in "dead
// zone" then ignore the message--don't pass to control bar
CPoint pt(lp);
if (OnToolHitTest(pt, NULL) == -1)
return 0; // return without handling: bypass control bar dragging!
}
// pass unhandled messages subclassed window--this is important!*/
return CMFCToolBar::WindowProc(msg, wp, lp);
}
};
//////////////////////////////
// in CMainFrame declaration
protected:
CLockedMFCMenuBar m_wndMenuBar;
CLockedMFCToolBar m_wndToolBar1;
CLockedMFCToolBar m_wndToolBar2;
////////////////////////////
// in CMainFrame::OnCreate
if (!m_wndToolBar1.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar1.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar2.LoadToolBar(theApp.m_bHiColorIcons ? IDR_MAINFRAME_256 : IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
EnableDocking(CBRS_ALIGN_ANY);
m_wndMenuBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar1.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_wndMenuBar);
DockPane(&m_wndToolBar2);
DockPane(&m_wndToolBar1);
DockPaneLeftOf(&m_wndToolBar1, &m_wndToolBar2);
m_wndMenuBar.SetPaneStyle(m_wndMenuBar.GetPaneStyle() &
~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
m_wndToolBar1.SetPaneStyle(m_wndToolBar1.GetPaneStyle() &
~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
m_wndToolBar2.SetPaneStyle(m_wndToolBar2.GetPaneStyle() &
~(CBRS_GRIPPER | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));
I've noticed a few visual problems when using the Office 2007 style too - it seems to be a little bit buggy. Can you use one of the others instead? XP Luna seems to be quite stable...