Toolbar TBSTYLE_FLAT issue - windows

If I create a toolbar and add the TBSTYLE_FLAT flag my toolbar ends up with a black background and the buttons behave funny, without the flag all is well except the separators don't show so the question is how do I use the TBSTYLE_FLAT properly so that the separators show but the background behaves as it should?
dwExStyle = nul
dwStyle = WS_CHILD + TBSTYLE_LIST + TBSTYLE_TOOLTIPS + CCS_NODIVIDER + TBSTYLE_FLAT
Edit: If I take out the TBSTYLE_FLAT and then send a TB_SETSTYLE message with TBSTYLE_FLAT before the window is shown then everything looks OK but the toolbar places itself at the bottom of the window and clicking a button shows the button rec to still be at the top of the window?
TBSTYLE_FLAT = 0x0800;
TB_SETSTYLE = 0x438;

Related

PyQt5 control windows

In the above imange the background window is the main window of the screen. Then follows one Form that opens from the menu of the Main Window
and at the top you can see a QMessageBox like this:
box = QMessageBox()
box.setIcon(QMessageBox.Question)
box.setWindowTitle('Αποθήκευση αλλαγών')
box.setText('Θέλετε να αποθηκεύσετε τις αλλαγές σας;')
box.setStandardButtons(QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
buttonY = box.button(QMessageBox.Yes)
buttonY.setText('Ναι')
buttonN = box.button(QMessageBox.No)
buttonN.setText('Οχι')
buttonC = box.button(QMessageBox.Cancel)
buttonC.setText('Ακύρωση')
box.exec_()
if box.clickedButton() == buttonY:
self.save_and_close(True)
self.main_self.manage_microphone_window_is_open = False
event.accept()
elif box.clickedButton() == buttonN:
self.main_self.manage_microphone_window_is_open = False
event.accept()
elif box.clickedButton() == buttonC:
event.ignore()
I want in the bottom the Windows (bottom bottom there that start menu of windows and clock are) to show only one program.
Any ideas?
With the help of musicmante i did the following:
I change Form Window to QDialog and set MainWindow as parent
I set a parent to box: box = QMessageBox(dlg)
Note than in step 1 when you copy paste the QWidgets from Form to new Dialog (in QtDesigner), you may change the title of window the icon of window the style of the window and perhaps any other window settings.

How can I get the same look as the standard with an owner draw menu?

I consider using an owner draw menu in a Windows application that should have the same look as the standard menu. (Reason: the standard menu doesn't work well in some mixed DPI situations.)
Currently I have a problem providing the correct width during WM_MEASUREITEM.
This is a screenshot of the Edit menu of notepad where each item has a shortcut.
We can see that there is a constant gap between the item texts and shortcut texts as if they were columns. It seems as if the widths of the item texts and the widths of the shortcut texts are retrieved separately, as the longest item text "Time/Date" reserves a shortcut width suitable for Ctrl+A while it only needs one for F5.
I could not find any API functionality where I can give the width of the item text and the shortcut text separately, nor did I find any metric specifying the size of the gap.
So my question is: Is it possible to achieve the desired behavior within the usual WM_MEASUREITEM message and if yes, how? If not, is there any other means to get this right or is it just not possible at all?
This is how ReactOS does it:
To measure a menu item:
if ((p = wcschr( lpitem->Xlpstr, '\t' )) != NULL) {
RECT tmprc = rc;
LONG tmpheight;
int n = (int)( p - lpitem->Xlpstr);
/* Item contains a tab (only meaningful in popup menus) */
/* get text size before the tab */
txtheight = DrawTextW( hdc, lpitem->Xlpstr, n, &rc,
DT_SINGLELINE|DT_CALCRECT);
txtwidth = rc.right - rc.left;
p += 1; /* advance past the Tab */
/* get text size after the tab */
tmpheight = DrawTextW( hdc, p, -1, &tmprc,
DT_SINGLELINE|DT_CALCRECT);
lpitem->dxTab += txtwidth;
txtheight = max( txtheight, tmpheight);
txtwidth += MenuCharSize.cx + /* space for the tab */
tmprc.right - tmprc.left; /* space for the short cut */
}
Then to draw it:
Text = lpitem->Xlpstr;
if(Text)
{
for (i = 0; Text[i]; i++)
if (Text[i] == L'\t' || Text[i] == L'\b')
break;
}
if(lpitem->fState & MF_GRAYED)
DrawTextW( hdc, Text, i, &rect, uFormat);
/* paint the shortcut text */
if (!menuBar && L'\0' != Text[i]) /* There's a tab or flush-right char */
{
if (L'\t' == Text[i])
{
rect.left = lpitem->dxTab;
uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
}
else
{
rect.right = lpitem->dxTab;
uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
}
DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
}
So to insert a keyboard accelerator in a menu item, you simply separate it from the item text with the tab character. The measuring and drawing code then looks for this tab character and acts accordingly.
Note, however, that for the keyboard accelerator to be right-aligned in the menu like it is in your screenshot (which is achieved with DrawText with DT_RIGHT) the drawing code expects it to be separated from the item text with the '\b' character, not the tab character, and unless I'm missing something this is not accounted for in the measuring code, so you might want to compensate for that.
Replicating the standard menu with owner draw is a world of pain. You have to deal with Visual Styles on and off, mnemonics/Access keys, accessibility and all the undocumented metrics. It is better just to use the normal menu if you can.
Per-monitor DPI support seems to change in every Windows 10 release. 1607 added EnableNonClientDpiScaling which scales the menu and other non-client areas. 1703 added Per Monitor v2 and MSDN says this about PMv2:
Scaling of non-client area - All windows will automatically have their non-client area drawn in a DPI sensitive fashion. Calls to EnableNonClientDpiScaling are unnecessary.
Scaling of Win32 menus - All NTUSER menus created in Per Monitor v2 contexts will be scaling in a per-monitor fashion.
Notepad is PMv2 and its menu seems to work fine:
Windows 8.1 and < 10 Anniversary Update will require more work and I would suggest that you just don't declare yourself DPI aware on these systems and let Windows scale your window for you (with some blurriness) if the system has multiple monitors.

Placeholder still visible when adding edit control to a CToolbar?

Years ago, I added an edit control to the toolbar in my application following directions similar to these:
http://www.codeproject.com/Articles/1106/Adding-a-Combo-Box-to-a-Docking-Toolbar
Similar directions can be found in many articles, so I think the procedure is fairly common. Until a few years ago, this worked fine, and the result was as shown in the article. However, I believe the move to XP changed the appearance of buttons in the toolbar, and instead I now see this in my application:
It seems as though the original instructions worked only because controls prior to the change occupied the entire height of the toolbar, so the edit control obstructed the separator behind it.
Ideally, I think the underlying separator should be made invisible. However, this doesn't seem to be handled explicitly in any of the articles I've found, and I'm not quite sure myself how to prevent the separator from being drawn.
Any help would be greatly appreciated. Thanks!
If you follow that article on codeproject exactly, you have probably modified the place holder into a separator from a button. This is why the separator line shown thru when the height of the button image is bigger than the height of the combo box.
If you keep the place holder as an empty button, you will not have such problem. A series of several place holder buttons may be needed in cascaded formation for a really useful length for the combobox.
This technique is demonstrated as follows:
// standard creation of the toolbar in CMainFrame::OnCreate
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
// status bar creation .....
// .....
// the place holders are a series of 5 empty toolbar buttons ie: ID_COMBO_1 to ID_COMBO_5
// get index of first combobox place holder
INT nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(ID_COMBO_1);
// get size of first place holder rectangle
CRect rcRect;
m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rcRect);
INT nWidth = rcRect.Width();
// calculate width of combobox with sum of all place holder (5 in total)
nWidth = nWidth * 5;
rcRect.top = 5; // top of combo box
rcRect.bottom = rcRect.top + 250; // drop height
rcRect.right = rcRect.left + nWidth;
// create the combobox to sit above the place holders
if(!m_comboBox.Create(CBS_DROPDOWNLIST | CBS_SORT | WS_VISIBLE |
WS_TABSTOP | WS_VSCROLL, rcRect, &m_wndToolBar, ID_COMBO_1))
{
TRACE(_T("Failed to create combo-box\n"));
return FALSE;
}
m_comboBox.AddString("Toolbar Combobox item one");
m_comboBox.AddString("Toolbar Combobox item two");
m_comboBox.AddString("Toolbar Combobox item three");
I've used this technique from CodeGuru. It's old, but, I've been using it for many years and it still works.

WinApi - How To Modify Console Window?

I want my console window to be modified. I got the handle. And this helps to change it. But how can I
remove close button
remove maximize button
remove icon
disable resizing
?
// C# syntax
StringBuilder buffer = new StringBuilder(260);
IntPtr window = FindWindow(null, buffer.ToString(0, GetConsoleTitle(buffer, buffer.Capacity)));
uint a = (uint)((WS_BORDER | WS_CAPTION) & (~WS_ICONIC));
SetWindowLongPtr(window, -16, new IntPtr(a)); // GWL_STYLE = -16
For some reason the window is broken after this call. I can't move it with the mouse anymore and all clicks go through it to other windows.
You removed all the window styles, and added back just WS_BORDER and WS_CAPTION. What you should do is:
Read the current window style with a call to GetWindowLongPtr.
Perform bitwise AND with the bitwise negation of the styles you want to remove.
Set the window style with a call to SetWindowLongPtr.

How to add a custom button to windows' minimize/maximize/close (x)

I was wondering if there is a way to add (programatically, of course) an icon/button/whatever besides plain text to a window (Microsoft Windows window...)'s title bar or next to where the minimize/maximize/close buttons are. I could draw it myself and create an illusion it is a part of the window, but I wonder if in the user32 api there is such a method.
So far, I found a way to disable the minimize/maximize/close buttons but not a way to add a custom one to them. It seems strange to me.
Here is what I am trying to achieve:
I have been wondering how it is done here, since drawing a button for every window using gdi/gdi+ and then detecting if it is overlapped by another window and then displaying only the non-overlapped part seems to me like an unlikely solution. Probably the button has been registered in the window class so that every window has this button. Any pointers what to do?
In addition, how do I create a button at all, assuming I DON'T have Unicode enabled. Then in the following piece of code:
HWND hwndCommandLink = CreateWindow(
L"BUTTON", // Class; Unicode assumed.
L"", // Text will be defined later.
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_COMMANDLINK, // Styles.
10, // x position.
10, // y position.
100, // Button width.
100, // Button height.
hDlg, // Parent window.
NULL, // No menu.
(HINSTANCE)GetWindowLong(hDlg, GWL_HINSTANCE),
NULL); // Pointer not needed.
SendMessage(clHwnd, WM_SETTEXT, 0, (LPARAM)L"Command link");
SendMessage(clHwnd, BCM_SETNOTE, 0, (LPARAM)L"with note");
I have to substitute all the nice Windows constants with their long equivalent....However, when I search for them, all i get is this:
http://msdn.microsoft.com/en-us/library/bb775951(v=VS.85).aspx
Any pointers?

Resources