Creating context menu for win32 API - winapi

I am trying to create context menu for win32 application using
case WM_RBUTTONDOWN:
{
HMENU hPopupMenu = CreatePopupMenu();
InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_CLOSE, (LPCWSTR)"Exit");
InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_EXIT, (LPCWSTR)"Play");
SetForegroundWindow(hWnd);
TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, 0, 0, 0, hWnd, NULL);
}
But I always get context menu as shown below
alt text http://img191.imageshack.us/img191/866/70219076.png
I want text exit and play to be displayed in the menu

You can't convert a string literal to wide by casting, you have to declare it as a wide char string. The casting just defeats the compiler warning, it doesn't change the content of the string.
change this
(LPCWSTR)"Exit"
(LPCWSTR)"Play"
to this
_T("Exit")
_T("Play")
or this
L"Exit"
L"Play"

Are you specifying the encoding in the API function definition? I ran into that problem recently and removing the specification fixed the problem.

Following worked for me
case WM_RBUTTONDOWN:
{
HMENU hPopupMenu = CreatePopupMenu();
InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_CLOSE, L"Exit");
InsertMenu(hPopupMenu, 0, MF_BYPOSITION | MF_STRING, ID_EXIT, L"Play");
SetForegroundWindow(hWnd);
TrackPopupMenu(hPopupMenu, TPM_BOTTOMALIGN | TPM_LEFTALIGN, 0, 0, 0, hWnd, NULL);
}

Related

Does the TB_LOADIMAGES message return a valid count?

Here is a fragment of my program, with the last line sending a TB_LOADIMAGES message to the newly-created toolbar.
hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, TEXT("This is the toolbar"), WS_CHILD | TBSTYLE_TOOLTIPS,
0, 500, 200, 32, hWndMain, (HMENU) ID_TOOLBAR, hInstance, NULL);
if (!hWndToolbar) return false;
const int numButtons = 3;
TBBUTTON tbButtonsAdd[numButtons] = {
{MAKELONG(HIST_BACK,0), IDM_ABOUT, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR) TEXT("junk")},
{MAKELONG(HIST_FORWARD,0), IDM_ABOUT, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR) TEXT("two")},
{MAKELONG(HIST_FAVORITES,0), IDM_ABOUT, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0}, 0, (INT_PTR) TEXT("three")}
};
debugInt = SendMessage(hWndToolbar, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
According to what I read here the return value from the SendMessage() should be the number of images in the image list, but I'm always seeing 0. Am I misreading the documentation? I would read the 0 as a fail.
The toolbar otherwise seems to work fine, and the images loaded are indeed there.
The documentation is misleading. The return value actually indicates the index of the first image added to the image list (i.e. the number of images that existed before the new ones were added).
So the first time you send this message (assuming you haven't previously assigned your own non-empty image list to the toolbar), 0 is the expected return for success. If you send the message again to add more images you'll see a different value returned.

How can I reveal a hidden window?

I want make a hidden window visible.
HWND hWnd = FindWindow(NULL, "MyWindowName");
ShowWindow(hWnd, SW_SHOW);
The window is found, but nothing happens. It remains hidden.
What am I doing wrong?
If it matters, the application is made using MFC and it has the following method overwritten:
void CMyClass::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
lpwndpos->flags &= ~SWP_SHOWWINDOW;
CDialog::OnWindowPosChanging(lpwndpos);
}
I did it.
Apparently you need to modify some flags.
long style= GetWindowLong(hWnd, GWL_STYLE);
style |= WS_VISIBLE;
SetWindowLong(hWnd, GWL_STYLE, style);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
And it works.

Add a new line using SetWindowText() Function

I have Created an Edit window.
I want one string to be displayed in one line and the other string to be displayed on the other line, but the code I am executing only displays the second string. below is my code snippet:
hWndEdit = CreateWindow("EDIT", // We are creating an Edit control
NULL, // Leave the control empty
WS_CHILD | WS_VISIBLE | WS_HSCROLL |
WS_VSCROLL | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
10, 10,1000, 1000,
hWnd,
0,
hInst,NULL);
SetWindowText(hWndEdit, TEXT("\r\nFirst string\r\n"));
SetWindowText(hWndEdit, TEXT("\r\nSecond string"));
OUTPUT:
You are only seeing the last line because SetWindowText() replaces the entire contents of the window in one go.
If you want to display both lines at one time, simply concatenate them together in a single call to SetWindowText():
SetWindowText(hWndEdit, TEXT("\r\nFirst string\r\n\r\nSecond string"));
On the other hand, if you want to insert them at different times, you have to use the EM_SETSEL message to place the edit caret at the end of the window and then use the EM_REPLACESEL message to insert text at the current caret position, as described in this article:
How To Programatically Append Text to an Edit Control
For example:
void AppendText(HWND hEditWnd, LPCTSTR Text)
{
int idx = GetWindowTextLength(hEditWnd);
SendMessage(hEditWnd, EM_SETSEL, (WPARAM)idx, (LPARAM)idx);
SendMessage(hEditWnd, EM_REPLACESEL, 0, (LPARAM)Text);
}
.
AppendText(hWndEdit, TEXT("\r\nFirst string\r\n"));
AppendText(hWndEdit, TEXT("\r\nSecond string"));
hWndEdit = CreateWindow("EDIT", // We are creating an Edit control
NULL, // Leave the control empty
WS_CHILD | WS_VISIBLE | WS_HSCROLL |
WS_VSCROLL | ES_LEFT | ES_MULTILINE |
ES_AUTOHSCROLL | ES_AUTOVSCROLL,
10, 10,1000, 1000,
hWnd,
0,
hInst,NULL);
SetWindowText(hWndEdit, TEXT("\r\nFirst string\r\n\r\nSecond string"));
or
SetWindowText(hWndEdit, TEXT("\r\nFirst string\r\n"));
char* buf = malloc(100);
memset(buf, '\0', 100);
GetWindowText(hWndEdit, (LPTSTR)buf, 100);
strcat(buf, "\r\nSecond string");
SetWindowText(hWndEdit, (LPTSTR)buf);

SetParent() (win32)

Any ideas how to use SetParent()?
The following doesn't seem to work:
fhWnd = FindWindow(_T("Notepad"), NULL);
hWnd = CreateWindowEx(WS_EX_TOPMOST , _T("test"), _T("test"),
WS_POPUP,
20, 20, 400, 400, NULL, NULL, hInst, NULL);
SetParent(hWnd, fhWnd);
DWORD style = GetWindowLong(hWnd, GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
SetWindowLong(hWnd, GWL_STYLE, style);
SetWindowLong(fhWnd, GWL_STYLE, GetWindowLong(fhWnd, GWL_STYLE) | WS_CLIPCHILDREN);
With the above code I have to move the parent window out of the screen and back in again in order to see what's draw on the child window.
Any idea what I am doing wrong?

Unable to create StatusBar in Visual C++ express 2010 using plain win32 api

I am using plain Win32 API (no MFC I mean) to create a simple app. I use CreateWindowEx with STATUSCLASSNAME as specified in MSDN but the handle returned is NULL. I made a call to InitCommonControlsEx as indicated but that returns FALSE! So I suspect that's the reason why the bar isn't created. What's going on? Please help.
I am on Windows 7 64 bit.
hStatusBar = ::CreateWindowExW(
0,
L"STATUSCLASSNAME",
L"",
WS_VISIBLE|WS_CHILD|WS_BORDER,
0,0,0,0, hWnd, 0, hInstance, NULL
);
There is one simple mistake in your code. STATUSCLASSNAME is not a value this is a constant from < commctrl.h >. So you code actually should looks like this:
#include <commctrl.h>
.
.
.
hStatusBar = ::CreateWindowExW(
0,
STATUSCLASSNAME,
L"",
WS_VISIBLE|WS_CHILD|WS_BORDER,
0,0,0,0, hWnd, 0, hInstance, NULL
);
I suppose you was looking into this http://msdn.microsoft.com/en-us/library/bb775491%28v=VS.85%29.aspx#STATUSCLASSNAME but as it specified, there are constants in the left column not values
if you are using W (wide) chars and functions you have to change constant name (see inside commcrtl.h). I used:
status = CreateWindowExW(0, STATUSCLASSNAMEW,
L"Spec.chars fine - Czech=Česky", WS_VISIBLE | WS_CHILD | WS_BORDER,
0, 0, 0, 0, hwnd, 0, NULL, NULL);
and is seems to be ok.

Resources