
ポップアップメニュー表示について質問です。
リソースファイルを使わずにポップアップメニューを
表示させたいのですが、どうすればいいのでしょうか?
このサイト↓
「http://msdn.microsoft.com/ja-jp/library/cc440880 …」
を見ても、私はVBは分からないので出来ませんでした。
他のサイトも調べてみたのですが、リソースファイルを使った
サンプルしかありませんでした。
開発環境:Visual Studio 2005
使用言語(分かる言語):C、C++
No.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;
}
//-------------------------------------------------------------
//ウィンドウ関連此処まで
//-------------------------------------------------------------
出来ました。
詳しく書いて頂きありがとうございます。
全然的外れではありませんでした。
最初に書かれていたもので良かったです。
質問に書いたリンク先がタスクトレイに表示させていたので、
タスクトレイに表示させるプログラムと思われたのでしょうか?
私の説明不足でお手間を取らせてしまって申し訳ありません。
ですけど、助かりました。
補足説明も参考にさせて頂きます。
No.2
- 回答日時:
こんばんは。
アイテムを追加する時は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;
}
No.1
- 回答日時:
「猫でもわかるプログラミング」さんのサイトに書いてあったんですね。
気づきませんでした。
参考になりました。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Directxについて
-
最早開始時間と最遅完了時刻を...
-
C言語 エラーの原因がわからな...
-
信頼区間の1.96や1.65ってどこ...
-
「Aに対するBの割合」と「Aに対...
-
For文の終了値を関数にしても問...
-
配列をnビットシフトする
-
数学 一次関数 関数 y=-3/4x+k(...
-
std::set<int> で、ある値が何...
-
Enterキーを押されたら次の処理...
-
sscanfとscanfの違いがよくわか...
-
main.c:7:43: warning: implici...
-
#define _CRT_SECURE_NO_WARNIN...
-
InvokeMemberメソッドとは何を...
-
【#define】 defineで定義した...
-
2の補数を計算するプログラム
-
a^2の√=a が成り立たない場合
-
2÷3などの余りについて
-
PICで小数点の演算
-
iTRONプログラミング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エディットボックスの背景の色...
-
エラー Run-Time Check Failur...
-
Win32APIでウィンドウを中央に...
-
ウィンドウサイズを変更しても...
-
音量調節
-
1~1000,1001~2000の間に素数が...
-
この列挙体でsysjanの関数はあ...
-
子ウインドウの作成と破棄について
-
Win32のファイルダイアログのサ...
-
ウィンドウ非表示に時に表示し...
-
COMPORTマルチスレッドで例外発生
-
ボタンの色(WINAPI)
-
マウスの反応
-
ポップアップメニュー
-
C言語win32api、エディットボッ...
-
ウィンドウが表示されない
-
WM_CREATE について
-
c言語のプログラミングでキーボ...
-
C++のcase文の書き方
-
LoadImageとSetCursorについて
おすすめ情報