SDKでツールバーの上下移動を可能にする方法

このQ&Aのポイント
  • SDK,WinXPで開発しています。ツールバーを画面の下部にユーザーが自由に移動できるようにしたいです。
  • 画面に沢山のウィンドウが張りついていて、各画面を好きな場所に移動できるアプリケーションをSDKで実現したいです。
  • 既存のものを少し改造してツールバーの上下移動を実現する方法を探していますが、SDKでは難しいかもしれません。
回答を見る
  • ベストアンサー

SDKでツールバーの上下移動を可能にしたい

SDK,WinXPで開発しています。(Developer Studio使用です) 現在レバーコントロールにツールバーやちょっとした設定を入れていますが、このツールバーを画面の下部(ステータスバーのすぐ上など)にユーザーが自由に移動可能にしたいのです。 これを実現する為にはレバーコントロールではダメだと思うのですが、どのような手法で行えば良いのでしょうか。 アプリケーションによくある、画面に沢山のウィンドウが張りついていて、各画面を好きな場所に移動したりするものを実現したいのです。 Builderなどならば実現可能なのは分かるのですが、今回はどうしても既存のものを少し改造して実現したいのです。 SDKではムリなのでしょうか。

  • mm666
  • お礼率92% (58/63)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  フローティングツールバーの事でしょうか。此れは説明出来る物ではありません。  先ずココを参考にしてください。  http://oshiete1.goo.ne.jp/qa2710782.html  途中でスタイルをポップアップにチェンジさせるとタスクバーが表示されてしまいます。ダミーウィンドウを指定しても意味が無い為、スタイルチェンジをせずに予め作成しておいた3種類のウィンドウに対して状況に応じてツールバーの乗せる換えをしながら、表示・非表示を切り替えます。  此れでもまだ一部分に過ぎません。以下参考に。 #include<windows.h> #include<commctrl.h> //リソースID const UINT IDC_TOOLBAR1 = 1000; //クラス名 const LPCSTR PSZ_APP = "app window"; const LPCSTR PSZ_DUMMY = "dummy window"; const LPCSTR PSZ_LAND = "land window"; const LPCSTR PSZ_FLOAT= "float window"; const LPCSTR PSZ_MOVE = "move window"; //浮揚ツールバーを構成するウィンドウ struct FLOATINGTB { HWND hWndLand;//着地ウィンドウ HWND hWndFloat;//浮揚ウィンドウ HWND hWndMove;//移動ウィンドウ HWND hToolBar;//ツールバー WNDPROC wndProcTBOld;//ツールバープロシージャ }; //アプリのデータ struct DATA { HWND hWndApp;//アプリウィンドウ HWND hWndDummy;//ダミーウィンドウ FLOATINGTB ftb;//浮揚ツールバーを構成する構造 }; //スタティック変数 static DATA s_data; //ちょっとした関数 static const RECT GetClientRect(HWND hWnd) { RECT rc; ::GetClientRect(hWnd, &rc); return rc; } //ちょっとした関数 static const POINT SetPoint(int x, int y) { const POINT pt = {x, y}; return pt; } //LPARAMを分解してPOINTにする関数 static const POINT PointFromLParam(LPARAM lParam) { const POINT pt = {(int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)}; return pt; } //マウスがウィンドウ内かどうか static bool IsMouseIn(HWND hWnd) { const RECT rc = ::GetClientRect(hWnd); POINT pt = {rc.left, rc.top}; POINT ptMouse = {0}; ::ClientToScreen(hWnd, &pt); ::GetCursorPos(&ptMouse); return (ptMouse.x > pt.x && ptMouse.x < pt.x + rc.right && ptMouse.y > pt.y && ptMouse.y < pt.y + rc.bottom); } //マウスがウィンドウ内の上半分にあるか static bool IsMouseUpper(HWND hWnd) { const RECT rc = ::GetClientRect(hWnd); POINT pt = {rc.left, rc.top}; POINT ptMouse = {0}; ::ClientToScreen(hWnd, &pt); ::GetCursorPos(&ptMouse); return (ptMouse.y > pt.y && ptMouse.y < pt.y + (rc.bottom / 2)); } //見ての通り static ATOM Regist(WNDPROC wndProc, LPCSTR pszClassName) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc= wndProc; wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.hIcon = ::LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = ::LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName= pszClassName; wndclass.hIconSm = ::LoadIcon(NULL, IDI_APPLICATION); return ::RegisterClassEx(&wndclass); } //見ての通り static HWND Open(int x, int y, int w, int h, LPCSTR lpszClassName, LPCSTR lpszWindowName = "NoName", HWND hParent = NULL, DWORD dwStyle = WS_OVERLAPPEDWINDOW, DWORD dwExStyle = 0, HMENU hMenu = NULL) { return ::CreateWindowEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle, x, y, w, h, hParent, hMenu, ::GetModuleHandle(NULL), NULL); } //ウィンドウのスタイルチェンジを真似する static void TransformWindow(HWND hWndTo, HWND hWndFrom, DWORD dwStyle, DWORD dwExStyle, LPPOINT pptFix = NULL) { //ツールバーハンドルを取り出す(hWndFromは必ずツールバーハンドルの所有者でないと駄目) HWND hToolBar = ::GetDlgItem(hWndFrom, IDC_TOOLBAR1); RECT rc = ::GetClientRect(hWndFrom); ::AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle); POINT pt = ::SetPoint(rc.left, rc.top); //ポインタがあれば指定された位置にウィンドウを移動する if(pptFix) { pt = *pptFix; } else//ポインタが無いのでhWndFromのクライアント座標をスクリーン座標に変換する { ::MapWindowPoints(hWndFrom, NULL, &pt, 1); } ::MoveWindow(hWndTo, pt.x, pt.y, rc.right - rc.left, rc.bottom - rc.top, TRUE); //ツールバーハンドルの親ウィンドウをhWndToにする ::SetParent(hToolBar, hWndTo); //hWndToを表示する ::ShowWindow(hWndTo, SW_SHOW); //hWndFromを非表示にする ::ShowWindow(hWndFrom, SW_HIDE); } //上・下を見分けてウィンドウを着地させる位置を返す static const POINT GetLandWindowPointHelper(DATA* pdata) { POINT pt = {0}; //マウスが下半分に居る if(::IsMouseUpper(pdata->hWndApp))return pt; //アプリウィンドウの縦幅から着地ウィンドウの縦幅を引いた場所がxの位置に成る RECT rc = ::GetClientRect(pdata->hWndApp); pt = ::SetPoint(0, rc.bottom - ::GetClientRect(pdata->ftb.hWndLand).bottom); return pt; } //ツールバーのプロシージャ LRESULT CALLBACK TBHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt = {0}; RECT rc = {0}; int iButton = 0; TBBUTTON tb = {sizeof(tb)}; switch(uMsg) { case WM_LBUTTONDOWN: //親ウィンドウが着地ウィンドウではないので勧めない if(::GetParent(hWnd) != s_data.ftb.hWndLand) break; //クリックされたマウス位置からツールボタンを探す pt = ::PointFromLParam(lParam); iButton = ::SendMessage(hWnd, TB_HITTEST, 0, (LPARAM)&pt); //ツールボタンが見つかったので勧めない if(::SendMessage(hWnd, TB_GETBUTTON, iButton, (LPARAM)&tb) == TRUE) break; //ココまで来るとツールバーのベルトがクリックされた事に成る //着地ウィンドウから移動ウィンドウへ変化 ::TransformWindow(s_data.ftb.hWndMove, s_data.ftb.hWndLand, WS_BORDER, 0); //ツールバーの再描写 ::UpdateWindow(hWnd); //移動ウィンドウへメッセージを送る ::SendMessage(s_data.ftb.hWndMove, WM_NCLBUTTONDOWN, HTCAPTION, lParam); return 0; } return ::CallWindowProc(s_data.ftb.wndProcTBOld, hWnd, uMsg, wParam, lParam); } //ダミーウィンドウのプロシージャ LRESULT CALLBACK WndProcDummy(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } //浮揚ツールウィンドウのプロシージャ LRESULT CALLBACK WndProcFloat(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt = {0}; RECT rc = {0}; switch(uMsg) { case WM_CLOSE: //閉じたら強制で着地 pt = GetLandWindowPointHelper(&s_data); ::TransformWindow(s_data.ftb.hWndLand, s_data.ftb.hWndFloat, WS_BORDER, 0, &pt); return 0; case WM_EXITSIZEMOVE: //マウスがアプリウィンドウ内に存在しないので着地しない if(!::IsMouseIn(s_data.hWndApp)) break; //着地点を決める pt = GetLandWindowPointHelper(&s_data); ::TransformWindow(s_data.ftb.hWndLand, s_data.ftb.hWndFloat, WS_BORDER, 0, &pt); break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } //移動ウィンドウのプロシージャ LRESULT CALLBACK WndProcMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt = {0}; RECT rc = {0}; switch(uMsg) { case WM_EXITSIZEMOVE: //アプリウィンドウの外側に居るので浮揚する if(!::IsMouseIn(s_data.hWndApp)) { ::TransformWindow(s_data.ftb.hWndFloat, s_data.ftb.hWndMove, WS_OVERLAPPEDWINDOW, WS_EX_TOOLWINDOW); } else//アプリウィンドウの内側に居るので着地する { //着地点を決める pt = GetLandWindowPointHelper(&s_data); ::TransformWindow(s_data.ftb.hWndLand, s_data.ftb.hWndMove, WS_BORDER, 0, &pt); } break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } //着地ウィンドウのプロシージャ LRESULT CALLBACK WndProcLand(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { POINT pt= {0}; RECT rc = {0}; TBBUTTON tb = {sizeof(tb)};//ボタン用の構造体 int i = 0; switch(uMsg) { case WM_CREATE: //ツールバーを作る s_data.ftb.hToolBar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_TABSTOP | WS_VISIBLE, 0, 0, 1, 1, hWnd, (HMENU)IDC_TOOLBAR1, ::GetModuleHandle(NULL), 0); ::SendMessage(s_data.ftb.hToolBar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); //取り合えずボタンを5個作成する for(i = 0; i < 5; ++i) { tb.fsState = TBSTATE_ENABLED; tb.iBitmap = -1; tb.idCommand = i; ::SendMessage(s_data.ftb.hToolBar, TB_INSERTBUTTON, 0, (LPARAM)&tb); } //サイズあわせ ::SendMessage(s_data.ftb.hToolBar, TB_AUTOSIZE, 0, 0); //アプリの矩形を取る rc = ::GetClientRect(s_data.hWndApp); //ツールバーの高さだけ入れ直す rc.bottom = ::GetClientRect(s_data.ftb.hToolBar).bottom; //クライアント矩形からウィンドウサイズを決める ::AdjustWindowRectEx(&rc, WS_BORDER, FALSE, 0); //最後にきっちりとリサイズ ::MoveWindow(hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); //ツールバーをサブクラス化 s_data.ftb.wndProcTBOld = (WNDPROC)::SetWindowLong(s_data.ftb.hToolBar, GWL_WNDPROC, (LONG)&::TBHookProc); break; case WM_NCHITTEST: return HTCAPTION; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } //アプリウィンドウのプロシージャ LRESULT CALLBACK WndProcApp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { RECT rc; switch(uMsg) { case WM_CREATE: //ココで入れておかないと他のウィンドウのWM_CREATEに間に合わない s_data.hWndApp = hWnd; //着地ウィンドウを作成(初期で可視) ::GetClientRect(hWnd, &rc); ::Regist(&::WndProcLand, PSZ_LAND); s_data.ftb.hWndLand = ::Open(0, 0, rc.right, 24, PSZ_LAND, PSZ_LAND, hWnd, WS_BORDER | WS_CHILD | WS_VISIBLE); //移動ウィンドウを作成(初期で不可視) ::Regist(&::WndProcMove, PSZ_MOVE); s_data.ftb.hWndMove = ::Open(0, 0, rc.right, 24, PSZ_MOVE, PSZ_MOVE, s_data.hWndDummy, WS_BORDER | WS_POPUP); //浮揚ツールウィンドウを作成(初期で不可視) ::Regist(&::WndProcFloat, PSZ_FLOAT); s_data.ftb.hWndFloat = ::Open(0, 0, rc.right, 24, PSZ_FLOAT, PSZ_FLOAT, hWnd, WS_OVERLAPPEDWINDOW, WS_EX_TOOLWINDOW); break; case WM_CLOSE: ::DestroyWindow(hWnd); break; case WM_DESTROY: ::PostQuitMessage(0); break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } //ウィンメイン int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MSG msg; //ポップアップウィンドウでタスクバーに表示しない為にダミーウィンドウを作成する //デスクトップの「縦・横」幅に合わせて作成 HDC hDC = ::GetDC(NULL); ::Regist(&::WndProcDummy, PSZ_DUMMY); s_data.hWndDummy = ::Open(0, 0, ::GetDeviceCaps(hDC, HORZRES), ::GetDeviceCaps(hDC, VERTRES), PSZ_DUMMY, PSZ_DUMMY, NULL, WS_POPUP); ::ReleaseDC(NULL, hDC); //アプリウィンドウの作成 ::Regist(&::WndProcApp, PSZ_APP); s_data.hWndApp = ::Open(20, 20, 640, 480, PSZ_APP); ::ShowWindow(s_data.hWndApp, iCmdShow); //決まり文句 while(::GetMessage(&msg, NULL, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return msg.wParam; }

mm666
質問者

お礼

machongolaさま、ありがとうございます。 お返事が遅くなり申し訳ありません。 頂いたソースで実際に動作した時は感動でした… 本当に簡単に説明頂けるようなものではないのですね。 もっと簡単に出来るのかと思っていました。 教えて頂いてから、探しても見つからないのは当然かと思いました。 頂いたものを参考にして、実際プログラムに上手く組み込めるかどうか、まだまだ時間がかかりそうです。 今回教えて頂けなかったら、ずっとつまずいたままでした。 感謝しきれないほどです。 ありがとうございました。

関連するQ&A

  • ツールバーの移動

    昨日までインタネット画面の最下部にあったツールバーが画面の最上部に いつの間にか移動してしまいました。 元通りにするのにはどうしたら良いのでしょうか?

  • ツールバーのビットマップの変更

    WinXP,SDKです。 たとえば、XP上で見たエクスプローラやIEのツールバーのボタンには、押した時に「押されている」状態になるものがあると思います。 IEのお気に入りのボタンなど。 押した時にこのボタンの背景が白に変化しています。(色は環境によって違うかも?) このような事を実現するにはどうすれば良いのでしょうか。 今、レバーコントロールにツールバーを置いています。 これらのボタンはすべて「TBSTYLE_CHECK」を指定してボタンのように使用しています。 このままだと、押しているものと押されていないものがぱっと見よく分かりません。 もちろん、押してあるものは背景の色も多少変わるし分からない訳ではないのですがもっと鮮明に分かるようにしたいのです。 そこで押してあるボタンのビットマップを変えたいと考えました。 ツールバーではこのような事は出来ないのでしょうか。

  • バイナリエディタの自作

    バイナリエディタを自作したいのですが、 どのようにしたらいいのか検討が付きません。 正確にはBzのようなバイナリ編集画面を作成したいのです。 開発環境は「Borland Developer Studio 2006」の「c++ Builder」になります。 情報をお持ちの方がいらっしゃいましたら どうぞお力をお貸しください。 よろしくお願い致します。

  • スクロールバーでのピクチャーコントロールやリストビューの移動

    お世話になります。 今回お聞きしたいことは MFCでダイアログ上にリストコントロールとスクロールバー、またはピクチャーコントロールとスクロールバーを設置した際に、スクロールバーの移動に伴って、リストコントロール内の列や、ピクチャーコントロールに表示されている画像の見えている箇所を移動させることが出来るかどうか。 です。 まだ、本格的にプログラムを作り始めてるわけではないのですが、事前にこのような動作が実現可能かどうかお聞きしたく、質問させて頂きました。 もしご存知の方がいましたら、参考になるHPや方法を教えていただければと思っています。参考になるHPがなくても、実現可能かどうかだけ教えて下さるだけでも結構ですので、宜しくお願い致します。 開発環境は Windows CE 6.0 Visual Studio 2005 です。

  • RectTrackerの実装

    Windows XP + SDK の環境で開発をしています。 画面に表示された矩形をグラフィカルに編集(矩形の移動や大きさの変更)したいと考えています。 MFCのCRectTrackerの機能をSDKで実現させるにはどの様な方法が考えられますか? 宜しくお願いします。

  • fire-fox2.0のツールバーカスタマイズについて

    fire-fox2.0について質問です。 環境: XP ブラウザ:fire-fox2.0.0.7 ツールバー領域の右クリックメニュー「カスタマイズ」より「ツールバーのカスタマイズ画面」を表示して、 ドラッグ&ドロップ操作でアイテムを追加・削除することができるはずなんですが、私のはなぜかできないんです。 昔はできていたのでカスタマイズやっていたんですが、 最近やってみたらなぜかできない。。 症状として、 ツールバー領域の右クリックメニュー「カスタマイズ」で、カスタマイズする画面はちゃんと表示されます。 ですがツールバー領域・アイコンなどにカーソルを乗せても、「矢印」の状態のままで「手の形」に変化しません。 アイコンをクリックした状態でドラッグしても、カーソルはぼやけた四角(通常のドラッグ状態)に変化せず「矢印」状態のままです。 ツールバーのカスタマイズ画面からの、アイコンなどを追加・削除は可能です。 ですが、「今現在表示されているアイコンの移動・削除ができない」んです。 またツールバーのカスタマイズ画面 ⇒ ツールバーを追加 で新しくツールバーを作ってみても、追加した時は一時的に追加状態(表示)されますが、「完了」をすると消えます。 現在インストールされているツールバーは、 ナビゲーションツールバー ブックマークツールバー yahooツールバー  Web developerツールバー googleツールバー の5つです。普段、yahooツールバーは表示させてませんがここでもちょっとした問題ありまして、このyahooツールバーを表示させようとしても、表示できる時とできない場合があります。(かなり気まぐれです) 何か変なアドインが邪魔でもしているんでしょうか。 昔、about:configの設定を一つだけ変更した記憶があるんですが、もしかしたら関係あるかもしれません。(どこかは覚えてません) 現在、ツールバーに表示されているアイコンの順番とかむちゃくちゃになってしまいました^^; また以前に別サイトで質問したのですが、 localstore.rdfというのを削除してみてもダメでした。 どなたか分かる方いましたら、教えてください<(_ _)>

  • ブラウザでpdfを見る際のツールバーの表示について

    ブラウザでpdfを見る際のツールバーの表示について質問させてください。 ブラウザでpdfファイルを開くと、pdf画面下部にマウスを移動した際にツールバーが出現します。 (ブラウザでのpdf表示はブラウザ依存だとは思いますが、少なくともIE, Firefoxでは出ます。) 具体的には、下記ページの目次最初の「PDF を閲覧モードで表示する」にある画像のものです。 http://help.adobe.com/ja_JP/acrobat/standard/using/WSe6c6ee3e336ebb13-630c189912be99aedab-7fff.html これを、pdf作成側の設定で非表示にすることはできますでしょうか。 よろしくお願いします。

  • デスクトップの設定が…(-_-;)

    「いつまでも初心者」 いつも画面下部にあったタスクバーが、ある日突然上部に移動して表示されるようになっています、立ち上げた時に知らずにどこかをクリックしていたのかも判りませんが、非常に使いづらくツールバーも変わってしまった様で、「もどる」「すすむ」の表示も無く「お気に入り」の表示が画面の左に出なくなっています、どうしたら直せるのでしょうかどなたか宜しくご指導願いますか。 色々と読み返してみましたが、どうも判りませんので御願い致します(T_T)。

  • 画面下部が使えない!?

    ThinkPad T20でWin2000を使ってます。 ちょっと前から画面の下部7~8mmが変なのです。 背景も前のが残ってしまっているし、底より下に ウィンドウを移動できません。 ついでにIME2000のツールバーも表示されません。 (プロパティでは画面端を確保に指定してあるのに・・・) これって故障ですか?

  • VC++からブラウザを起動して・・・

    VC++&MFCで画面を作成しています。 作成した画面のあるボタンをクリックすると、規定のブラウザが起動され、 指定したURLを表示にいくという処理を行いたいので、 ShellExecute( NULL, "open", "http://xxx.xxx.co.jp/", NULL, NULL, SW_SHOWNORMAL ); という様な感じでブラウザを起動しているのですが、このブラウザの起動時に、 アドレスバー・ツールバー等を非表示にしたいのです。 ShellExecute()じゃなくても良いので、VC++(SDK、MFC何でも可)で 実現する方法はあるのでしょうか?。 よろしくお願いします。

専門家に質問してみよう