はじめまして。
現在、VC++2005(Vista)でタスクトレイ常駐型のBiffプログラムを作ろうとしています。
タスクトレイに格納する部分と、タスクトレイ格納時に最初の1回バルーンを表示させる
ところまでは、できたのですが、バルーン内の文言を変更するところができません。
CChildDlg::OnInitDialogで値を設定し、Shell_NotifyIcon(NIM_ADD, &ni);で表示させ
て、別関数内で、ni.szInfoTitleとni.szInfoに文字列をstrcpyで設定し、
Shell_NotifyIcon(NIM_MODIFY, &ni)で更新できるか?と思ったのですが、文字列の設定
は成功してそうなのですが、Shell_NotifyIcon(NIM_MODIFY, &ni)がFALSEが返ってきます。
ソースも載せず、わかりにくい質問で申し訳ございませんが、ご教授願えませんでしょうか?
宜しくお願いいたします。
ソースが提示されていないので詳しくはわかりませんが、
VC7.0 XPでkeitaと同じ方法でバルーン文字を変えることが出来ます。
Vista特有な事象でしょうか・・・?
>keitaと同じ方法で
keitaさんと同じ方法で
失礼しましたw
ーさん、コメントありがとうございます。
>Vista特有な事象でしょうか・・・?
自分のソースにも自信がないので、???という状況です。
空の親画面があって、ボタンを配置した子画面があります。
プログラム起動時はタスクトレイのみ表示し、タスクトレイ右クリックメニューから「表
示」を選択するとボタン配置した子画面を表示してます。
子画面のボタンを押したときに文言を変えたいと思ってます。
下記のようなタスクトレイの関数を作って、子のOnInitDialogで引数をADDにして成功。
子画面のボタンを押したときのOnButton内で引数をMODにしてみたのですが、失敗という
状況です。
デバッグでみると更新時にハンドル値が”評価できません”となっているのが原因かな?
と思うのですが、この作り方ではハンドル取得できないのでしょうか?
void CChildDlg::SetTaskTrayIcon(int nFlg)
{
memset(&ni, 0, sizeof(NOTIFYICONDATA));
ni.cbSize = sizeof(NOTIFYICONDATA);
ni.uID = 0;
ni.hWnd = m_hWnd;
ni.uFlags = NIF_ICON | NIF_MESSAGE ;
ni.hIcon = AfxGetApp()->LoadIconA( IDR_MAINFRAME );
ni.uCallbackMessage = WM_USER_POPUP;
ni.uFlags = (ni.uFlags | NIF_INFO );
ni.dwInfoFlags = NIIF_INFO;
switch( nFlg )
{
case ADD:
lstrcpy(ni.szInfoTitle, 追加タイトル);
lstrcpy(ni.szInfo, 追加本文);
Shell_NotifyIcon( NIM_ADD, &ni );
break;
case MOD:
lstrcpy(ni.szInfoTitle, 更新タイトル);
lstrcpy(ni.szInfo, 更新本文);
Shell_NotifyIcon( NIM_MODIFY, &ni );
break;
case DEL:
Shell_NotifyIcon( NIM_DELETE, &ni );
break;
default:
break;
}
}
アプリがロードしているShell32.dllは、本当にver5.0以上でしょうか?
vistaだとsxsが・・・
+さん、コメントありがとうございます。
>アプリがロードしているShell32.dllは、本当にver5.0以上でしょうか?
\Windows\system32内の、Shell32.dllのプロパティで確認したところ、ファイルバージョンは
6.0.6000.16513
となっている様子です。
アプリがロードしているというのは、プログラム側で別途バージョンやパスを指定しなく
てはならないのでしょうか?
質問ばかりで申し訳ございませんが、よろしくお願いいたします。
XPで検証してみたところ、同じくADDで成功し、MODIFYやDELETEで失敗するみたいです。
やっぱりプログラムの作り方が悪いようです・・・
んー・・・。
自分のソースではこんな感じ(長いです)
//グローバル
NOTIFYICONDATA ni ;
BOOL HogeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ni.cbSize = NOTIFYICONDATA_V2_SIZE ;
ni.uID = 0 ;
ni.hWnd = m_hWnd ;
ni.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP ;
ni.hIcon = theApp.LoadIcon(IDR_MAINFRAME) ;
ni.uVersion = NOTIFYICON_VERSION ;
ni.uCallbackMessage = WM_TRYCLK ;
::lstrcpy( ni.szTip , チップ ) ;
ni.dwInfoFlags = NIIF_INFO ;
::lstrcpy( ni.szInfo , いんふぉ) ;
::lstrcpy( ni.szInfoTitle , たいとる) ;
::Shell_NotifyIcon( NIM_SETVERSION , &ni ) ;
::Shell_NotifyIcon( NIM_ADD , &ni ) ;
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返しま
す。
}
void HogeDlg::OnBnClickedButton1()
{
ni.uFlags |= NIF_INFO ;
ni.uTimeout = 10 ;
::Shell_NotifyIcon( NIM_MODIFY , &ni ) ;
ni.uFlags ^= NIF_INFO ;
ni.uVersion = NOTIFYICON_VERSION ;
::Shell_NotifyIcon( NIM_MODIFY , &ni ) ;
}
void HogeDlg::OnCancel()
{
::Shell_NotifyIcon( NIM_DELETE , &ni ) ;
CDialog::OnCancel();
}
ちょっと気になった点。
WM_USER + nをトレイメッセージに使っている様子ですが
Win32ならWM_APP + nをユーザーメッセージとして使うべき。
WM_USERは、Win16時代の遺物とどこかで読んだような・・・。
+さん、コメントありがとうございます。
サンプルソースまで、ご提示いただきまして恐縮です。
できました!!
感謝、感激です。
ありがとうございます。
・見えないダイアログA
・タスクトレイなどを出すダイアログB(画面サイズ0・右クリックメニュー実装)
・設定画面ダイアログC(Bの右クリックで起動)
の3画面があって、BからC画面の呼び出しを行ってました。
BのOnInitDialogでタスクトレイアイコン追加して、Cのボタンが押された際にB内の別関
数でアイコンを変更しようとしていましたが、これではご提示いただいたサンプルでも無
理でした。
よくよく考えると「B画面にボタンなどを追加し、設定画面として配置したらC画面なんか
要らんか?」と思い、作成し直しました。
A・B画面の状態で、ご提示いただいたサンプルで試したところOnInitでアイコン追加さ
れ、ボタン押下時にバルーン表示されました。
ただ、現状では起動時に設定画面がでてしまうので、右クリック時に初めて設定画面を出
そうと思うので、SW_HIDE/SW_SHOWなどで表示切替をしようと思います。
すみません。
解決チェックを忘れておりました。