Disable Maximize Button c++ console application - c++

I am maintaining old C++ application running console. I has disabled "close" buttun . I need to disable maximize button as well. The following code disabes the close button
DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
DrawMenuBar(GetConsoleWindow());
I have added line to disable maximize button:
DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_MAXIMIZE, MF_BYCOMMAND);
DrawMenuBar(GetConsoleWindow());
It works, the button is disabled but it is not greyed out. (The Close button is greyed out)
What am I missing?
Thank you.

Use SetWindowLong to change the window style, then call SetWindowPos. Example:
HWND hwnd = GetConsoleWindow();
DWORD style = GetWindowLong(hwnd, GWL_STYLE);
style &= ~WS_MAXIMIZEBOX;
SetWindowLong(hwnd, GWL_STYLE, style);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_FRAMECHANGED);

Related

How to make tab key work in C++ Win32 API

I am a noob for C++ Win32 API. I am trying to make a textbox (edit control). In the textbox, I want to make the tab key act as it would in notepad, i.e., it would advance the cursor to the next tab stop in a textbox. I made a simple edit control with some scrollbars, auto-scrolling and multiline styles. I want the tab key to advance the cursor to the next tab stop. But it doesn't happen. The tab key doesn't do anything, literally nothing. It acts as if it wasn't assigned to do any task inside an edit control.
If anyone knows how to do that, I would be really grateful to him.
Here's the full code which I used for creating an edit control :-
HWND hTb = CreateWindow
(
L"Edit", L"LOL",
WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL | ES_WANTRETURN | WS_TABSTOP,
0, 0, LOWORD (lp), HIWORD (lp),
hWnd, NULL, NULL, NULL
);
I am creating hTb in the WM_CREATE message of the WndProc. This edit control is just used for resizing it and nothing complicated. Here's the code :-
case WM_SIZE :
{
MoveWindow (hTb, 0, 0, LOWORD (lp), HIWORD (lp), TRUE);
break;
}
Thanks in advance.
Edit controls will not receive tabs if "the dialog manager" portion of Win32 is engaged. For a modeless dialog box, the way you will see dialog box semantics showing up in a window is if the application's main message loop is filtering messages with the API call IsDialogMessage. IsDialogMessage will reroute tab presses to the window rather than the focused control, in this case the edit box.
To fix the problem use a standard message loop. That is,
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
not
while(GetMessage(&msg, NULL, 0, 0))
{
if (!IsDialogMessage(hwnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
You can read more about the dialog manager on Raymond Chen's blog: here, here, and here

Shell_NotifyIcon: Tray icon show both - popup menu and taskbar menu [duplicate]

I create a notification icon with:
notifyIcon.cbSize = sizeof(NOTIFYICONDATA);
notifyIcon.hWnd = mainWnd;
notifyIcon.uID = 100;
notifyIcon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
notifyIcon.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LOGO));
notifyIcon.dwState = NIS_SHAREDICON;
notifyIcon.uVersion = NOTIFYICON_VERSION;
notifyIcon.uTimeout = 15000;
notifyIcon.uCallbackMessage = APP_MSG_TRAY;
wcscpy_s(notifyIcon.szTip, 127, WTXT_APP_TRAY_TOOLTIP);
Shell_NotifyIcon(NIM_ADD, &notifyIcon);
Shell_NotifyIcon(NIM_SETVERSION, &notifyIcon);
And have a context menu popup on WM_RBUTTONDOWN and WM_CONTEXTMENU like this:
MENUITEMINFO separatorBtn = {0};
separatorBtn.cbSize = sizeof(MENUITEMINFO);
separatorBtn.fMask = MIIM_FTYPE;
separatorBtn.fType = MFT_SEPARATOR;
HMENU hMenu = CreatePopupMenu();
if(hMenu) {
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_OPEN_OPTIONS, WTXT_OPTIONS);
InsertMenuItem(hMenu, -1, FALSE, &separatorBtn);
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_MSG_EXIT, WTXT_EXIT);
POINT pt;
GetCursorPos(&pt);
SetForegroundWindow(mainWnd);
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, mainWnd, NULL);
PostMessage(mainWnd, WM_NULL, 0, 0);
DestroyMenu(hMenu);
}
It works fine, but the context menu doesn't disappear always. Sometimes (often) if you have ie. winamp and my app icons in system tray, if you right click my app and winamp afterwards, bot menus will appear, and my menu won't disappear automatically until you click an item.
Any ideas?
thanks...
To display a context menu for a notification icon, the current window must be the foreground window before the application calls TrackPopupMenu or TrackPopupMenuEx. Otherwise, the menu will not disappear when the user clicks outside of the menu or the window that created the menu (if it is visible).
SetForegroundWindow(hDlg);
TrackPopupMenu( hSubMenu,
TPM_RIGHTBUTTON,
pt.x,
pt.y,
0,
hDlg,
NULL);
Do not catch WM_RBUTTONDOWN but WM_RBUTTONUP. And of course do not handle both WM_RBUTTONUP and WM_CONTEXTMENU, since they will both get handled and you'd show the context menu twice for every right-click.
Showing the menu twice would have the effect you describe: the menu shows up, but doesn't seem to disappear (because it shows up again right away a second time).
There are apps to try to hack around the restrictions of the notification area (tray) API. They'll hook the Explorer window and listen for Windows messages. That lets them do stuff that isn't otherwise possible but it inevitably destabilizes other apps. Getting two context menus is a sure sign of this kind of trouble.
You've got a good lead on what kind of program may do this, it's got an icon. Kill them one by one until you find the evil-doer. Not much you can do about it probably, other than not running it or complaining to the vendor.
You seem to already have both of the documented bugfixes (SetForegroundWindow & WM_NULL) I'd say anything beyond this is a bug in windows.
If you really want to do hacky things, you could probably get the menu window handle in WM_INITMENU* (And I don't mean the HMENU, but the HWND for the menu) and hide that window.

How to change app icon in taskmanager

I have some windows application that can change his icon, using win api functions
SendMessage(hwnd, WM_SETICON, ICON_BIG, icon_handle);
SendMessage(hwnd, WM_SETICON, ICON_SMALL, icon_handle);
Shell_NotifyIcon(...);
It changes icon in taskbar and tray (taskbar notification area), but icon in taskmanager still not changed.
How can I change icon in taskmanager? Is it possible?
From this SO answer
It's important to change all icons, including the application, both small and big:
//Change both icons to the same icon handle.
SendMessage(hwnd, WM_SETICON, ICON_SMALL, hIcon);
SendMessage(hwnd, WM_SETICON, ICON_BIG, hIcon);
//This will ensure that the application icon gets changed too.
SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_SMALL, hIcon);
SendMessage(GetWindow(hwnd, GW_OWNER), WM_SETICON, ICON_BIG, hIcon);
EDIT:
According to the this SO answer, the icon needs to be a .ICO file created by an icon editor; this SO article also mentions that you need to send the message to the top-most window of the application.
I could switch the icon in the task bar, alt-tab and in the task manager by
a) creating an icon using the Visual Studio Resource Editor
b) loading the icon with code like HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1));
c) sending WM_SETICON, ICON_SMALL to the topmost window -- I was using a MFC SDI application, so I sent the message to the main frame window (AfxGetApp()->m_pMainWnd)
NOTE: a comment in the MSDN Docs for WM_SETICON mentions
The system does not make a copy of the icon. Do not destroy the icon before destroying the window
It is a general Windows bug. Task manager and explorer remember icons associated with files for a very long time. If your icon has lowest ID in exe, it should appear as the application icon in task manager (root node). But if you changed it recently, it may not work. The icon of the window itself is a quite different thing - if it isn't displaying, your code is wrong.
BOOL sendWndIconToTaskbar(HWND hWnd,HICON hIcon)
{
BOOL ret = TRUE;
ASSERT(hWnd);
if(!::IsWindow(hWnd))
return FALSE;
CWnd* pWnd;
pWnd = pWnd->FromHandle(hWnd);
ASSERT(pWnd);
if(!pWnd)
return FALSE;
if(pWnd->GetParent())
{
if(::SetWindowLong(hWnd,GWL_HWNDPARENT,NULL) == 0)
return FALSE;
}
if(!(pWnd->ModifyStyle(NULL,WS_OVERLAPPEDWINDOW)))
ret = FALSE;
pWnd->SetIcon(hIcon,TRUE);
pWnd->SetIcon(hIcon,FALSE);
return ret;
}
HICON hIconSm = (HICON)LoadImage(NULL, "default.ico", IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
sendWndIconToTaskbar(pOcxDlg->m_hWnd,hIconSm);

How to create win7 style button using CreateWindowEx [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
winapi CreateWindowEx -> create button with user system styles?
Hi,
I am kinda new to WinAPI and C++ and I am using Visual Studio 2010. I want to create some buttons in the main window. So there are two questions:
1) can I use a dialog window created with resource editor as a main window so that I wouldnt have to create all controls "by hand" in the "post-WM_CREATE message" section?
2) (If I cant use resource script made window with buttons as a main window) When I "hand make" button using CreateWindowEx like this:
case WM_CREATE:
{
HFONT buttonFont = CreateFont(-11, 0, 0, 0, 400, FALSE, FALSE, FALSE, 1, 400, 0, 0, 0, fontButtonFont);
HWND bMainOK = CreateWindowEx(
0,
WC_BUTTON,
szOkButton,
WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON,
24, 200, 75, 23,
hWnd,
0,
hInst,
0);
SendMessage(bMainOK, WM_SETFONT, (WPARAM)buttonFont, FALSE);
}
I get very ugly oldstyle button. How do I make it look like Win7/Vista button? Or better how do I make it behave as system style setting says (when using XP get XP style button, when using Vista get Vista style button etc.)?
Thanks
You need to link a manifest to your app that specifies v6 common controls. Websearch will do the rest for you.

System tray context menu doesn't disappear

I create a notification icon with:
notifyIcon.cbSize = sizeof(NOTIFYICONDATA);
notifyIcon.hWnd = mainWnd;
notifyIcon.uID = 100;
notifyIcon.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
notifyIcon.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LOGO));
notifyIcon.dwState = NIS_SHAREDICON;
notifyIcon.uVersion = NOTIFYICON_VERSION;
notifyIcon.uTimeout = 15000;
notifyIcon.uCallbackMessage = APP_MSG_TRAY;
wcscpy_s(notifyIcon.szTip, 127, WTXT_APP_TRAY_TOOLTIP);
Shell_NotifyIcon(NIM_ADD, &notifyIcon);
Shell_NotifyIcon(NIM_SETVERSION, &notifyIcon);
And have a context menu popup on WM_RBUTTONDOWN and WM_CONTEXTMENU like this:
MENUITEMINFO separatorBtn = {0};
separatorBtn.cbSize = sizeof(MENUITEMINFO);
separatorBtn.fMask = MIIM_FTYPE;
separatorBtn.fType = MFT_SEPARATOR;
HMENU hMenu = CreatePopupMenu();
if(hMenu) {
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_OPEN_OPTIONS, WTXT_OPTIONS);
InsertMenuItem(hMenu, -1, FALSE, &separatorBtn);
InsertMenu(hMenu, -1, MF_BYPOSITION, APP_MSG_EXIT, WTXT_EXIT);
POINT pt;
GetCursorPos(&pt);
SetForegroundWindow(mainWnd);
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, mainWnd, NULL);
PostMessage(mainWnd, WM_NULL, 0, 0);
DestroyMenu(hMenu);
}
It works fine, but the context menu doesn't disappear always. Sometimes (often) if you have ie. winamp and my app icons in system tray, if you right click my app and winamp afterwards, bot menus will appear, and my menu won't disappear automatically until you click an item.
Any ideas?
thanks...
To display a context menu for a notification icon, the current window must be the foreground window before the application calls TrackPopupMenu or TrackPopupMenuEx. Otherwise, the menu will not disappear when the user clicks outside of the menu or the window that created the menu (if it is visible).
SetForegroundWindow(hDlg);
TrackPopupMenu( hSubMenu,
TPM_RIGHTBUTTON,
pt.x,
pt.y,
0,
hDlg,
NULL);
Do not catch WM_RBUTTONDOWN but WM_RBUTTONUP. And of course do not handle both WM_RBUTTONUP and WM_CONTEXTMENU, since they will both get handled and you'd show the context menu twice for every right-click.
Showing the menu twice would have the effect you describe: the menu shows up, but doesn't seem to disappear (because it shows up again right away a second time).
There are apps to try to hack around the restrictions of the notification area (tray) API. They'll hook the Explorer window and listen for Windows messages. That lets them do stuff that isn't otherwise possible but it inevitably destabilizes other apps. Getting two context menus is a sure sign of this kind of trouble.
You've got a good lead on what kind of program may do this, it's got an icon. Kill them one by one until you find the evil-doer. Not much you can do about it probably, other than not running it or complaining to the vendor.
You seem to already have both of the documented bugfixes (SetForegroundWindow & WM_NULL) I'd say anything beyond this is a bug in windows.
If you really want to do hacky things, you could probably get the menu window handle in WM_INITMENU* (And I don't mean the HMENU, but the HWND for the menu) and hide that window.