Today I have another specific question about a new feature in windows 7 called the thumbnail toolbar or the Aero Peek Toolbar if some might like to call it that way. I have been able to create a new set of toolbar buttons for my application each button with its unique icon and behavior But I haven't been able to add functionality to the new buttons as the new THUMBUTTON structure does not specify any action parameter for a button object.
Here is a code snippet to show you what I've used to create the buttons:
ITaskbarList4* pitskbar;
HRESULT hr = CoInitialize(NULL);
hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pitskbar));
HWND hwnd = AfxGetMainWnd()->GetSafeHwnd();
DWORD dwMask = THB_BITMAP | THB_FLAGS;
THUMBBUTTON thbButtons[3];
thbButtons[0].dwMask = (THUMBBUTTONMASK)dwMask;
thbButtons[0].iId = 0;
thbButtons[0].iBitmap = 0;
thbButtons[0].dwFlags = THBF_ENABLED;
thbButtons[1].dwMask = (THUMBBUTTONMASK)dwMask;
thbButtons[1].iId = 1;
.
.
<More Button Params>
.
.
CImageList m_imglst;
m_imglst.Create(16, 16, ILC_COLOR16, 0, 4);
HICON icon = (HICON)::LoadImage(theApp.m_hInstance, MAKEINTRESOURCE(IDI_ICON_ON), IMAGE_ICON, 16, 16, LR_SHARED);
m_imglst.Add(icon);
.
.
<More Images>
.
.
hr = pitskbar->ThumbBarSetImageList(hwnd, m_imglst);
if (SUCCEEDED(hr))
{
hr = pitskbar->ThumbBarAddButtons(hwnd, ARRAYSIZE(thbButtons), thbButtons);
}
pitskbar->Release();
I would appreciate any helpful answer as long as it is in the question's context.
Regards
this is what you looking for?
"When a button in a thumbnail toolbar is clicked, the window associated with that thumbnail is sent a WM_COMMAND message with the HIWORD of its wParam parameter set to THBN_CLICKED and the LOWORD to the button ID."
source: http://msdn.microsoft.com/en-us/library/dd391703(VS.85).aspx
Here is a article on how to do it using the managed wrappers... by having a look at the managed wrapper, you might more easily see how to do it using C++...
Related
Following code adds a shield icon to a button:
SendMessage(btn1.Handle, BCM_SETSHIELD, 0, 1);
I've tried the same with checkboxes, radio button groups etc. Nothing works except a button.
Is there a way to add the shield icon to any other control?
Is there a way to add the shield icon to any other control?
If the control in question supports the display of a HICON (e. g. a static control), you can load the standard shield icon by calling LoadIconWithScaleDown with the IDI_SHIELD constant and assign that to the control.
int cx = GetSystemMetrics( SM_CXSMICON );
int cy = GetSystemMetrics( SM_CYSMICON );
HICON hShieldIcon = NULL;
HRESULT hr = LoadIconWithScaleDown( NULL, MAKEINTRESOURCE( IDI_SHIELD ), cx, cy,
&hShieldIcon );
if( SUCCEEDED( hr ) )
{
// Consult the reference on how to assign the HICON to the control.
}
If the control in question does not support assigning a HICON, you could use custom-draw, which is supported by many controls, to draw the icon yourself.
The documentation says:
Sets the elevation required state for a specified button or command link to display an elevated icon.
This implies that the only supported controls are buttons and command links.
I need to make tooltip a little bit right and lower to mouse cursor, but i can't do it in any way, tried different coordintaes but nothing seems to work. Where is the problem? Thank you.
// Add the new tooltip (if available)
if (m_LastToolTipRow!=-1 && m_LastToolTipRow!=-1)
{
// Not using CToolTipCtrl::AddTool() because it redirects the messages to CListCtrl parent
TOOLINFO ti = {0};
ti.cbSize = sizeof(TOOLINFO);
ti.uFlags = TTF_IDISHWND | TTF_TRANSPARENT; // Indicate that uId is handle to a control
ti.uId = (UINT_PTR)m_hWnd; // Handle to the control
ti.hwnd = m_hWnd; // Handle to window to receive the tooltip-messages
ti.hinst = AfxGetInstanceHandle();
ti.lpszText = LPSTR_TEXTCALLBACK;
m_OwnToolTipCtrl.SendMessage(TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
m_OwnToolTipCtrl.SendMessage(TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(pt.x + 100, pt.y + 100));
m_OwnToolTipCtrl.SendMessage(TTM_TRACKACTIVATE, true, (LPARAM)&ti);
m_OwnToolTipCtrl.Activate(TRUE);
//Multiline
m_OwnToolTipCtrl.SetMaxTipWidth(256);
//m_OwnToolTipCtrl.SetMaxTipWidth(SHRT_MAX);
}
TTF_IDISHWND
Indicates that the uId member is the window handle to the tool. If this flag is not set, uId is the tool's identifier.
According to this, the window with m_hWnd handle is the one that shows the tooltip and you can position the window itself. If you meant a tooltip separate to that window than there is a principal problem there.
I have a win32 application that runs full screen when started. The application has some button which invoke pop up dialogs.
Is there a way to make the entire desktop (except the pop up) go transparent black unless the pop up is dismissed by the user? what I am talking of is similar to windows 7 UAC pop ups and the background it causes.
Is it possible to do similar stuff for a full screened window app?
It is possible do this…sort of. Perhaps I should say, you can simulate this effect. It won't actually be like the UAC dialog, as the user will still be able to interact with other running applications. There is no such concept as "system modal" available to applications. That's by design, of course. But you can certainly show a "light box" that dims out the rest of the desktop and forces focus on your app's dialog box.
The way I would do it is to create a giant layered window that sits on top of all other windows and covers the entire screen, fill it with black, and set the opacity as desired. Then, before you show a modal dialog (either by calling the MessageBox function or using the DialogBox function to show one of your own custom dialogs), display your light box window. Finally, after the user dismisses the modal dialog, you will destroy the light box window.
Here's some sample code. Error checking is omitted for brevity. So is other good style, like wrapping this mess up in one or more classes.
INT_PTR ShowLightBoxedDialog(HINSTANCE hInstance,
LPCTSTR pDlgTemplate,
HWND hwndParent,
DLGPROC pDlgProc,
BYTE opacityLevel)
{
const TCHAR szLightBoxClass[] = TEXT("LightBoxWndClass");
// Register the light box window class.
static bool lightBoxRegistered = false;
if (!lightBoxRegistered)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_NOCLOSE | CS_SAVEBITS;
wcex.lpfnWndProc = LightBoxWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hIconSm = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = NULL;
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szLightBoxClass;
RegisterClassEx(&wcex);
lightBoxRegistered = true;
}
// Create and display the light box window.
HWND hwndLightBox = CreateWindowEx(WS_EX_NOACTIVATE | WS_EX_LAYERED,
szLightBoxClass,
NULL,
WS_POPUPWINDOW,
0, 0, 0, 0,
hwndParent,
NULL,
hInstance,
NULL);
SetLayeredWindowAttributes(hwndLightBox, 0, opacityLevel, LWA_ALPHA);
SetWindowPos(hwndLightBox,
HWND_TOP,
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN),
SWP_SHOWWINDOW);
// Display the modal dialog box (as you normally would).
// NOTE: The dialog box won't appear centered on the screen.
// For that, you will need to write centering code in response
// to the WM_INITDIALOG message in the dialog procedure.
INT_PTR result = DialogBox(hInstance, pDlgTemplate, hwndLightBox, pDlgProc);
//
// For demonstration purposes, I used the following code:
// INT_PTR result = MessageBox(hwndLightBox,
// TEXT("OH NOEZ!\n\nYour system is kaput! Abandon þe all hope."),
// NULL,
// MB_ABORTRETRYIGNORE | MB_ICONERROR);
// Destroy the light box window.
DestroyWindow(hwndLightBox);
// Return the result of the modal dialog box.
return result;
}
You'll notice that basically what I've done is created a wrapper around the DialogBox function, which you use whenever you want a dialog box with a "light box" effect. It takes all of the same parameters (the first 4), and then there's an additional one tacked on the end that allows you to specify the opacity level used for the "light box" effect. Something in the range of 150–200 is probably good. Naturally, you could pick something and hard-code it, but I suffer from severe allergies to hard-coded values. Anyway, it's super easy to call this function from anywhere:
ShowLightBoxedDialog(hInstance, /* your application instance */
MAKEINTRESOURCE(IDD_SAMPLE), /* your dialog template */
hWnd, /* parent window for dialog */
SampleWndProc, /* ptr to dialog procedure */
175); /* light box opacity level */
Because the code takes advantage of how modal dialogs already work in Windows, the user won't be able to interact with any other pieces of your application until they dismiss the dialog box. And because the "light box" window is positioned on top of everything else, it eats all mouse clicks and prevents setting focus to any other application. But it is trivial to work around using something like Alt+Tab.
So this is not a security feature! It is merely a visual effect!
And because it's just a silly visual effect, it's likely to be a frustrating one for your users. I don't actually recommend using it. But now you know how to do it. Wield such power responsibly, etc.
What I read is that the menu must have its MenuInfo.dwStyle flag set to MNS_NOTIFYBYPOS, what I did is:
MENUINFO MenuInfo;
memset(&MenuInfo,0, sizeof(MenuInfo));
MenuInfo.cbSize = sizeof(MenuInfo);
HMENU hPopupMenu = CreatePopupMenu();
GetMenuInfo(hPopupMenu, &MenuInfo);
MenuInfo.dwStyle |= MNS_NOTIFYBYPOS;
SetMenuInfo(hPopupMenu, &MenuInfo);
And next proceed with adding items:
InsertMenu(hPopupMenu, pos, MF_BYPOSITION, id , "do command");
Next track it:
TrackPopupMenu(hPopupMenu, TPM_CENTERALIGN | TPM_RETURNCMD, cursorPos.x, cursorPos.y, 0, hwnd, NULL);
But it has no effect, it compiles without error but the clicking event is till send as WM_COMMAND
You need to set the fMask member of the MENUINFO structure to tell the system which fields you want to set/get.
E.g.
MenuInfo.fMask = MIM_STYLE;
GetMenuInfo(hPopupMenu, &MenuInfo);
MenuInfo.dwStyle |= MNS_NOTIFYBYPOS;
SetMenuInfo(hPopupMenu, &MenuInfo);
Also note that the docs say:
MNS_NOTIFYBYPOS is a menu header style and has no effect when applied
to individual sub menus.
So it is possible that it won't work for you anyway with a popup menu.
I am trying to use the IFileOpenDialog to pick both files and folders (in multi-select mode) from the same dialog. I was able to add a custom button to the dialog and achieve what i want to do. Now i want to remove the default "Open" button from the dialog because its behavior is dependent on the order of selection. If a file is selected first and then a folder (multiselect), I get the OnFileOk event but if a user selects a folder first then a file, a click on the open button opens the first selected folder. Is there a way to remove or hide the Open button ??
My idea was to enumerate the child windows of IFileDialog and remove the child with caption "Open" and class "Button". I tried enumerating the child windows of IFileOpenDialog before doing the show, but I get only one child with class "Button" but its caption is "start". I cannot find a standard way of hiding the "Open" button. Please let me know if there is any other way of doing this.
Thanks,
Abhinay.
Buke's method worked for me but you have to wait until the dialog controls are created. It seems like every time the dialog is created OnFolderChange() is called so I just added my hiding code there:
STDMETHODIMP FileDialogEventHandler::OnFolderChange(IFileDialog* fileDialog) {
IOleWindow *pWindow = NULL;
HRESULT hr = fileDialog->QueryInterface(IID_PPV_ARGS(&pWindow));
if (SUCCEEDED(hr)) {
HWND hwndDialog;
hr = pWindow->GetWindow(&hwndDialog);
HWND openButton = GetDlgItem(hwndDialog, IDOK);
ShowWindow(openButton, SW_HIDE);
pWindow->Release();
}
return S_OK;
}
If you know the dialog item number (You can find the button ID using Spyxx), you may be able to do something like this:
HWND hOpenButton = GetDlgItem( hDlg, itemID );
ShowWindow( hOpwnButton, SW_HIDE );
IFileDialogCustomize::RemoveControlItem