タスクトレイにアイコンを格納し、
右クリックでそこからポップアップメニューを開くようにしています。
カーソルを動かしたときにCreateWindowEx関数でレイヤードウインドウ次々に作成しているのですが
子ウインドウ作成時(エフェクト放出時)に開いているポップアップメニューが閉じられてしまいます。
この現象は他のソフトウェアのポップアップウインドウでは起こってないので
ウインドウメッセージのやり取りか?とも思っています。
ポップアップメニューを維持し続ける方法はあるでしょうか?
改善策が見つからなければ右クリックでダイアログ作成に逃げるしかないかと思っています。
何か気になるところがありましたらご指摘ください。お願いします。
開発中のソフトウェアも添付させていただきます。
/////////////////////////////////////////////////////////////////////////////////////////////////////
//関数名 :MakeMenu関数
//機能 :右クリックメニューを作成する
//引数 :
//戻り値 :
/////////////////////////////////////////////////////////////////////////////////////////////////////
void CIconShell::MakeMenu(HWND hWnd2){
POINT pt;
//右クリックメニューを作る
GetCursorPos(&pt);
TrackPopupMenu(hSub,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd2,NULL);
return;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//関数名 :CreateChild
//機能 :子ウインドウを描写して初期設定を行い画像を描写する
//引数 :親ウインドウのハンドルとLPARAM
//戻り値 :
/////////////////////////////////////////////////////////////////////////////////////////////////////
int CEffect::CreateChild(HWND hParentWnd,LPARAM lp,DATA *WndData){
POINT pt;
HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hParentWnd,GWL_HINSTANCE);
//LPARAMから構造体の取得
MSLLHOOKSTRUCT *pmh;
pmh = (MSLLHOOKSTRUCT *)lp;
if(hParentWnd == NULL){
MSE("親ウインドウのハンドルが取得できません");
throw CError();
}
//子ウインドウを描写する
WndData->hChild = CreateWindowEx(WS_EX_LAYERED|WS_EX_TRANSPARENT,"STATIC",
NULL,
WS_POPUP|WS_VISIBLE,
(pmh->pt.x) - (nWidth / 2),(pmh->pt).y - (nHeight / 2),0,0,hParentWnd,NULL,hInst,NULL);
if(WndData->hChild == NULL){
MSE("子ウインドウを生成できません");
throw CError();
}
//ウインドウのパラメーター初期設定
GetCursorPos(&pt); //カーソル位置の取得
WndData->nAlpha = 255; //アルファ値を設定
//加速度を設定
WndData->nAccY = 2;
WndData->nAccX = rand() % 5 + 1;
WndData->nFirstAccY = rand() % 3 + 5;
//座標の初期化
WndData->wndSize.cx = nWidth;
WndData->wndSize.cy = nHeight;
//座標の初期化
WndData->wndPos.x = pt.x - (WndData->wndSize.cx / 2);
WndData->wndPos.y = pt.y - (WndData->wndSize.cy / 2);
//放出方向の決定
WndData->bRetrunFlag = rand() % 2;
//描写フラグの設定
WndData->bReleaseFlag = true;
//ここまで
//ここから作成した子ウインドウにエフェクト画像を初期描写する
if(nWidth == 0 || nHeight == 0){
MSE("画像情報が取得できませんでした");
throw CError();
}
// ウィンドウの形状をビットマップに合わせて変更
SetWindowPos(WndData->hChild, HWND_TOPMOST, 0, 0, nWidth, nHeight, SWP_NOMOVE | SWP_NOZORDER);
//常に最前面に描写
//ここをフラグ調整して外せば放出先がデスクトップオンリーになります
SetWindowPos(WndData->hChild,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
// 各種デバイスコンテキストの取得
hsdc = GetDC(0); // デスクトップのデバイスコンテキスト(色情報指定用)
hdc = GetDC(WndData->hChild); // このウィンドウのデバイスコンテキスト
hmemdc = CreateCompatibleDC(hdc); // hdcの互換デバイスコンテキスト
// デバイスコンテキストにおけるレイヤの位置
POINT po;
po.x = po.y = 0;
// レイヤードウィンドウの指定
BLENDFUNCTION blend;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = WndData->nAlpha; // 不透明度(レイヤードウィンドウ全体のアルファ値)
blend.AlphaFormat = AC_SRC_ALPHA;
// 画像を描画をする
hOldObj = SelectObject(hmemdc, hBitmap);
BitBlt(hdc, 0, 0, nWidth, nHeight, hmemdc, 0, 0, SRCCOPY|CAPTUREBLT);
//レイヤードウィンドウの更新
if (0 == UpdateLayeredWindow(WndData->hChild, hsdc, &WndData->wndPos, &WndData->wndSize, hmemdc, &po, 0, &blend, ULW_ALPHA)) {
MSE("レイヤーが更新できませんでした");
throw CError();
}else{
//ShowWindow(WndData->hChild,SW_NORMAL);
}
SelectObject(hmemdc, hOldObj);
DeleteDC(hmemdc);
ReleaseDC(WndData->hChild, hdc);
ReleaseDC(0, hsdc);
return 0;
}