プロが教える店舗&オフィスのセキュリティ対策術

ポップアップメニュー表示について質問です。

リソースファイルを使わずにポップアップメニューを
表示させたいのですが、どうすればいいのでしょうか?
このサイト↓
http://msdn.microsoft.com/ja-jp/library/cc440880 …
を見ても、私はVBは分からないので出来ませんでした。
他のサイトも調べてみたのですが、リソースファイルを使った
サンプルしかありませんでした。

開発環境:Visual Studio 2005
使用言語(分かる言語):C、C++

A 回答 (3件)

 こんにちは。


 すんません、思いっきり的ハズレな事を書いてしまいました。
 タスクトレイ中にリソースを使わず、ポップアップメニューを表示する手法のお話でしょうか。
 取り敢えず、以下は左クリックでタスクトレイ⇔ウィンドウの切り替えを行い、タスクトレイ中に右クリックでポップアップメニューを表示、メニューアイテムクリックでメッセージボックスを表示します。
 参考程度に。

#include<windows.h>
#include<tchar.h>

//タスクトレイ中のメッセージ
const DWORD WM_ICONTRAY = WM_USER + 1;

//メニューアイテムのID
const UINT IDM_OPEN= 100;
const UINT IDM_SAVE= 101;
const UINT IDM_OVERWRITE= 102;
const UINT IDM_DELETE= 103;

//ポップアップメニューハンドルの作成
static HMENU _S_hMenuPopup = ::CreatePopupMenu();

//-------------------------------------------------------------
//タスクバー関連此処から
//-------------------------------------------------------------
//タスクバーへ追加
static VOID AddTaskBar(HWND hWnd)
{
NOTIFYICONDATA nid = {sizeof(nid)};
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.hWnd = hWnd;
nid.uCallbackMessage = WM_ICONTRAY;
nid.hIcon = ::LoadIcon(NULL, IDI_WINLOGO);
::_tcscpy(nid.szTip, TEXT("タスク化テスト"));
::Shell_NotifyIcon(NIM_ADD, &nid);
}

//タスクバーから解除
static VOID RemoveTaskBar(HWND hWnd)
{
NOTIFYICONDATA nid = {sizeof(nid)};
nid.hWnd = hWnd;
::Shell_NotifyIcon(NIM_DELETE, &nid);
}
//-------------------------------------------------------------
//タスクバー関連此処まで
//-------------------------------------------------------------

//-------------------------------------------------------------
//メニューアイテム関連此処から
//-------------------------------------------------------------
//メニューアイテムの追加
static VOID AddMenuItem(HMENU hMenu, WORD wID, LPCTSTR pszName)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask= MIIM_ID | MIIM_STRING;
mii.fType= MFT_STRING;
mii.wID= wID;
mii.dwTypeData= (LPTSTR)pszName;
mii.cch= ::_tcslen(pszName);
::InsertMenuItem(hMenu, wID, FALSE, &mii);
}

//メニューセパレータの追加
static VOID AddMenuSep(HMENU hMenu, WORD wPos)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask = MIIM_TYPE;
mii.fType = MFT_SEPARATOR;
::InsertMenuItem(hMenu, wPos, TRUE, &mii);
}

//メニューアイテムから名前を取り出す
static VOID GetMenuName(HMENU hMenu, WORD wID, LPTSTR pszNameOut, DWORD dwStrLen)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask = MIIM_STRING;
mii.dwTypeData = pszNameOut;
mii.cch = dwStrLen;
mii.wID = wID;
::GetMenuItemInfo(hMenu, wID, FALSE, &mii);
}
//-------------------------------------------------------------
//メニューアイテム関連此処まで
//-------------------------------------------------------------

//-------------------------------------------------------------
//ウィンドウ関連此処から
//-------------------------------------------------------------
//ウィンドウクラスの登録
static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc)
{
WNDCLASSEX wndclass = {sizeof(wndclass)};
wndclass.hCursor= ::LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon= NULL;
wndclass.lpszMenuName= NULL;
wndclass.lpszClassName= szClassName;
wndclass.hbrBackground= (HBRUSH)::GetStockObject(BLACK_BRUSH);
wndclass.hInstance= ::GetModuleHandle(NULL);
wndclass.style= CS_BYTEALIGNCLIENT | CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc= wndProc;
wndclass.cbClsExtra= 0;
wndclass.cbWndExtra= 0;
return ::RegisterClassEx(&wndclass);
}

//ウィンドウを作成
static HWND Open(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h)
{
HINSTANCE hInst = ::GetModuleHandle(NULL);

HWND hWnd = ::CreateWindowEx(0, szClassName, szTitleName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT, w, h,
NULL, (HMENU)NULL,
hInst, NULL);
return hWnd;
}

//ウィンドウプロシージャ
LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
//ポップアップメニューハンドルへアイテムの追加
::AddMenuItem(_S_hMenuPopup, IDM_OPEN, TEXT("開く"));
::AddMenuItem(_S_hMenuPopup, IDM_SAVE, TEXT("保存"));
::AddMenuItem(_S_hMenuPopup, IDM_OVERWRITE, TEXT("上書き"));
::AddMenuItem(_S_hMenuPopup, IDM_DELETE, TEXT("削除"));

//「上書き」の下にセパレータを入れてみる
::AddMenuSep(_S_hMenuPopup, 3);
break;

case WM_DESTROY:
//ポップアップメニューハンドルを始末する
::DestroyMenu(_S_hMenuPopup);
::PostQuitMessage(0);
return 0;

case WM_CLOSE:
::DestroyWindow(hWnd);
return 0;

case WM_LBUTTONDOWN:
//タスクトレイ化する
::ShowWindow(hWnd, SW_HIDE);
::AddTaskBar(hWnd);
break;

case WM_COMMAND:
{
//メニューアイテムが押されると此処へ飛んでくる
const WORD wID = LOWORD(wParam);

//メニューアイテム名を受け取るバッファ
TCHAR tcbuf[MAX_PATH];
::GetMenuName(_S_hMenuPopup, wID, tcbuf, MAX_PATH);

//押されたのはアイテムを確認する
switch(wID)
{
case IDM_OPEN:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case IDM_SAVE:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case IDM_OVERWRITE:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case IDM_DELETE:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
}
break;
}

case WM_ICONTRAY://タスクトレイ中のメッセージ
switch(lParam)
{
case WM_LBUTTONDOWN:
//タスクトレイからウィンドウへ復帰
::ShowWindow(hWnd, SW_SHOW);
::RemoveTaskBar(hWnd);
break;

case WM_RBUTTONDOWN:
{
//ポップアップメニューを表示
POINT pt;
::GetCursorPos(&pt);
::TrackPopupMenuEx(_S_hMenuPopup, TPM_LEFTALIGN, pt.x, pt.y, hWnd, NULL);
}
break;
}
}
return ::DefWindowProc(hWnd, msg, wParam, lParam);
}

//見ての通り
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine, int nCmdShow)
{
MSG msg;

LPCTSTR szClassName = TEXT("my task tray popup menu window class");
if(::Regist(szClassName, &::MainWndProc) == 0)
return 0;

HWND hWnd = ::Open(szClassName, TEXT("タスクトレイ~ポップアップ表示のテスト"), 640, 480);
if(hWnd == NULL)
return 0;

::ShowWindow(hWnd, SW_SHOW);
::UpdateWindow(hWnd);

while(::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}

return msg.wParam;
}
//-------------------------------------------------------------
//ウィンドウ関連此処まで
//-------------------------------------------------------------
    • good
    • 0
この回答へのお礼

出来ました。
詳しく書いて頂きありがとうございます。

全然的外れではありませんでした。
最初に書かれていたもので良かったです。

質問に書いたリンク先がタスクトレイに表示させていたので、
タスクトレイに表示させるプログラムと思われたのでしょうか?
私の説明不足でお手間を取らせてしまって申し訳ありません。
ですけど、助かりました。
補足説明も参考にさせて頂きます。

お礼日時:2009/04/16 18:21

 こんばんは。


 アイテムを追加する時はIDから、セパレータを追加する時は番号で追加します。文字列を受け取る際には、受け取りバッファと要素数を渡します。
 以下参考程度に(ダイアログで処理しています)。

 「MENUITEMINFO構造体」
 http://yokohama.cool.ne.jp/chokuto/urawaza/struc …

//取り敢えず不精する
static HMENU _S_hMenuPopup = ::CreatePopupMenu();

//アイテムの追加
VOID AddMenu(HMENU hMenu, WORD wID, LPCTSTR pszName)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask = MIIM_ID | MIIM_STRING;
mii.fType = MFT_STRING;
mii.wID = wID;
mii.dwTypeData = (LPTSTR)pszName;//変更されないのでconstを外しても問題はない
mii.cch= ::_tcslen(pszName);

//http://msdn.microsoft.com/ja-jp/library/cc364793 …
//IDで追加する
::InsertMenuItem(hMenu, wID, FALSE, &mii);
}

//セパレータの追加
VOID AddSep(HMENU hMenu, WORD wPos)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask = MIIM_TYPE;
mii.fType = MFT_SEPARATOR;

//http://msdn.microsoft.com/ja-jp/library/cc364793 …
//アイテム番号から追加する(0から数える)
::InsertMenuItem(hMenu, wPos, TRUE, &mii);
}

//メニューアイテムから名前を取り出す
VOID GetMenuName(HMENU hMenu, WORD wID, LPTSTR pszNameOut, DWORD dwStrLen)
{
MENUITEMINFO mii = {sizeof(mii)};
mii.fMask = MIIM_STRING;
mii.dwTypeData = pszNameOut;
mii.cch = dwStrLen;
mii.wID = wID;

//http://msdn.microsoft.com/ja-jp/library/cc364689 …
//IDから探す
::GetMenuItemInfo(hMenu, wID, FALSE, &mii);
}

//プロシージャ内
INT CALLBACK DlgProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
switch(iMsg)
{
case WM_INITDIALOG:
{
//アイテムの追加
::AddMenu(_S_hMenuPopup, 100, "開く");
::AddMenu(_S_hMenuPopup, 101, "保存");
::AddMenu(_S_hMenuPopup, 102, "上書き");

//3番目にセパレータの追加(0から数える)
::AddSep(_S_hMenuPopup, 3);

//その下にアイテムの追加
::AddMenu(_S_hMenuPopup, 103, "削除");
return TRUE;
}

case WM_DESTROY:
{
//用が無くなり次第消す
::DestroyMenu(_S_hMenuPopup);
return TRUE;
}

case WM_CONTEXTMENU:
{
//マウスのスクリーン位置
POINT pt;
::GetCursorPos(&pt);

//http://msdn.microsoft.com/ja-jp/library/cc364839 …
//xを左隅に併せて表示する
::TrackPopupMenuEx(_S_hMenuPopup, TPM_LEFTALIGN, pt.x, pt.y, hwnd, NULL);
return TRUE;
}

case WM_COMMAND:
{
//押せたら此処に飛び込んでくる
const WORD wID = LOWORD(wParam);

//文字列の受け取りバッファを用意する
TCHAR tcbuf[MAX_PATH];
::GetMenuName(_S_hMenuPopup, wID, tcbuf, MAX_PATH);

switch(wID)
{
case 100:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case 101:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case 102:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
case 103:
::MessageBox(NULL, tcbuf, tcbuf, IDOK);
break;
}
return TRUE;
}
default:
return FALSE;
}
return TRUE;
}
    • good
    • 0

第42章 メニューにBMP表示


http://www.kumei.ne.jp/c_lang/sdk/sdk_42.htm

CreateMenu
CreatePopupMenu

に注目。
    • good
    • 0
この回答へのお礼

「猫でもわかるプログラミング」さんのサイトに書いてあったんですね。
気づきませんでした。
参考になりました。
ありがとうございます。

お礼日時:2009/04/16 18:34

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!