トップページ > 過去ログ > 記事閲覧
実行画面を上に移動して固定したい
名前:s707 日時: 2012/02/09 02:52

実行画面を上にドラッグして放すと ドラッグする前の位置にy座標が戻ってしまいます。 上以外は問題ないです。 下や左右に移動しても座標が戻ることはありません。 どうすればこの状態を解消できるでしょうか? ご助力の程、よろしくお願いします。 #include <windows.h> #define APP_NAME TEXT("Sample_MainWindow") int x = 0; int y = 0; LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush; RECT rect; GetWindowRect(hWnd, &rect); int height = rect.top; switch(uMsg) { case WM_LBUTTONDOWN: if(height < 0) MoveWindow( hWnd, x, y - 100, 400, 200, TRUE); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; case WM_PAINT: hBrush = CreateHatchBrush(HS_DIAGCROSS , RGB(0xFF , 0 , 0)); hdc = BeginPaint(hWnd , &ps); GetClientRect(hWnd , &rect); SelectObject(hdc , hBrush); Rectangle(hdc , 0 , 0 , rect.right , rect.bottom); EndPaint(hWnd , &ps); DeleteObject(hBrush); return 0; case WM_KEYUP: if (wParam == VK_ESCAPE) DestroyWindow(hWnd); return 0; case WM_NCHITTEST: return HTCAPTION; } return DefWindowProc(hWnd , uMsg , wParam , lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR lpCmdLine, int nCmdShow) { WNDCLASS wc; MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL , IDI_APPLICATION); wc.hCursor = LoadCursor(NULL , IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = APP_NAME; if (!RegisterClass(&wc)) return 0; if (CreateWindow(APP_NAME , TEXT(__FILE__) ,WS_POPUP | WS_VISIBLE, x , y, 400 , 200 , NULL , NULL , hInstance , NULL) == NULL) return 0; while(GetMessage(&msg , NULL , 0 , 0) > 0) { DispatchMessage(&msg); } return msg.wParam; }

Page: 1 |

Re: 実行画面を上に移動して固定したい ( No.1 )
名前:Will 日時:2012/02/09 09:49

ここでDXライブラリ未使用ソフトの質問をするのは不適当かと思います。 C言語何でも質問サイト http://dixq.net/
Re: 実行画面を上に移動して固定したい ( No.2 )
名前:s707 日時:2012/02/09 12:42

一ヶ月前にそちらのサイトで未解決の質問です。 勉強不足だったので解決としましたが。 コードは記載してませんが、DXライブラリを使用して デスクトップクロックを制作しています。 少し勉強し直したのですが、同じ質問はし辛かったので、こちらに投稿しました。
Re: 実行画面を上に移動して固定したい ( No.3 )
名前:tare 日時:2012/02/09 14:14

ウィンドウの生成にDXライブラリを用いれば解決します。
Re: 実行画面を上に移動して固定したい ( No.4 )
名前:s707 日時:2012/02/09 16:07

Will様、tare様、ご返信ありがとうございます。 こちらが前回のやりとりです。DXライブラリを使用してウィンドウを生成していると思います。 ttp://dixq.net/forum/viewtopic.php?f=3&t=9890
Re: 実行画面を上に移動して固定したい ( No.5 )
名前:いっち 日時:2012/02/09 19:55

これが正解といえるのか分かりませんが、とりあえず私の環境では何とかなりました。 ウィンドウプロシージャに以下のコードを足してみてください。 > static int top = 0; > > switch(uMsg) { // <- ここは既存 > case WM_MOVING: > { > LPRECT p = (LPRECT)lParam; > top = p->top; > break; > } > case WM_WINDOWPOSCHANGING: > { > WINDOWPOS* p = (WINDOWPOS*)lParam; > p->y = top; > break; > }
Re: 実行画面を上に移動して固定したい ( No.6 )
名前:s707 日時:2012/02/09 22:47

いっち様、ご返信ありがとうございます。 おかげさまで出来ました。 case文に{}をつけるのを初めて見ました。 まだ見ぬウィンドウメッセージも 一杯あるようです。 DXライブラリを使用したプログラムに これらのメッセージを実装するには どの様にすればいいでしょうか? プログラム実行時に出てくる ウィンドウとウィンドウクラスを破棄。 その後新しいウィンドウプロシージャに 今回のコードを追加して作成。 ウィンドウクラスを登録後 ウィンドウを作成。 この手順で試してみましたが 新しく作成したウィンドウがすぐに 消えてしまいます。 ウィンドウクラスを破棄する UnregisterClass関数の第1引数は ウィンドウクラス名らしいので ttp://ワールドワイドウェブ.gesource.jp/weblog/?p=417 こちらを使用してクラス名を調べました。 //main.cpp #include <windows.h> #include "DxLib.h" #include "dayData.h" #include "draw_clock.h" #include "Setup.h" #define APP_NAME TEXT("clock") #define chara_width 64 void jihou(struct dayData* day); void plan(struct dayData* day); void Time(struct dayData* day); void date(struct dayData* day); void version(struct dayData* day); int title(int,struct dayData* day); LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int top = 0; switch(uMsg) { case WM_MOVING: { LPRECT p = (LPRECT)lParam; top = p -> top; break; } case WM_WINDOWPOSCHANGING: { WINDOWPOS* p = (WINDOWPOS*)lParam; p -> y = top; break; } case WM_DESTROY: PostQuitMessage(0); return 0; case WM_KEYUP: if (wParam == VK_ESCAPE) DestroyWindow(hWnd); return 0; case WM_NCHITTEST: return HTCAPTION; } return DefWindowProc(hWnd , uMsg , wParam , lParam); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){ if(FindWindow(APP_NAME , NULL) != NULL ){ MessageBox(NULL , TEXT("多重起動を確認しました") , NULL , MB_OK); return 0; } struct dayData day[450]; // マウス状態管理用変数 int nClickNow = 0 , nClickPrev = 0; int nClickNow_R = 0 , nClickPrev_R = 0; int nClickR_Count = 0; int status = 0,temp = 0; bool menu_flg = false; // 画面モードの変更 SetGraphMode( 1680 , 1050 , 32 ) ;//パソコンの解像度に合わせる SetMainWindowText("clock"); ChangeWindowMode( TRUE ); // ウインドウの透過色モードON SetUseBackBufferTransColorFlag( TRUE ) ; SetWindowStyleMode(2); SetAlwaysRunFlag( TRUE ) ; if ( DxLib_Init( ) == -1 ) return -1; /*HWND hwnd = GetMainWindowHandle(); DestroyWindow(hwnd); UnregisterClass( (LPCTSTR)APP_NAME , hInstance);*/ WNDCLASS wc; // MSG msg; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL , IDI_APPLICATION); wc.hCursor = LoadCursor(NULL , IDC_ARROW); wc.hbrBackground= (HBRUSH)GetStockObject(HOLLOW_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName= APP_NAME; RegisterClass(&wc); CreateWindow(APP_NAME , TEXT(__FILE__) ,WS_POPUP | WS_VISIBLE, CW_USEDEFAULT , CW_USEDEFAULT, 840 , 525 , NULL , NULL , hInstance , NULL); SetDrawScreen(DX_SCREEN_BACK); Load_Graph(); Setup_load(day);//設定を読み込む plan(day);//予定を音声再生する int NewMouse = 0, OldMouse = GetMouseInput( ); while (ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0){ if((NewMouse = GetMouseInput()) != OldMouse && NewMouse & MOUSE_INPUT_LEFT) { SendMessage(GetMainWindowHandle(), WM_NCLBUTTONDOWN, HTCAPTION, 0);//ウインドウを移動させる為、ウインドウ枠をクリックしたと思わせる } OldMouse = NewMouse; //処理を省略         } DxLib_End(); return 0; } 下記のコメントを解除して実行しました。 新しいウィンドウはドラッグで移動出来ませんでした。 古いウィンドウの方は変化なしです。 /*HWND hwnd = GetMainWindowHandle(); DestroyWindow(hwnd); UnregisterClass( (LPCTSTR)APP_NAME , hInstance);*/
Re: 実行画面を上に移動して固定したい ( No.7 )
名前:いっち 日時:2012/02/09 23:26

以下のような感じでどうでしょうか? //- 以下、テストコード -// #include "DxLib.h" LRESULT CALLBACK WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int top = 0; switch(uMsg) { case WM_MOVING: { LPRECT p = (LPRECT)lParam; top = p -> top; break; } case WM_WINDOWPOSCHANGING: { WINDOWPOS* p = (WINDOWPOS*)lParam; p -> y = top; break; } case WM_NCHITTEST: return HTCAPTION; } return 0; } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { ChangeWindowMode( TRUE ); SetWindowText( "DxLib:" DXLIB_VERSION_STR ); ChangeWindowMode( TRUE ); SetUseBackBufferTransColorFlag( TRUE ); SetWindowStyleMode(2); SetAlwaysRunFlag( TRUE ); SetHookWinProc( WindowProc ); if ( DxLib_Init( ) == -1 ) return -1; int white = GetColor( 255, 255, 255 ); int NewMouse = 0, OldMouse = GetMouseInput( ); SetDrawScreen( DX_SCREEN_BACK ); while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { if((NewMouse = GetMouseInput()) != OldMouse && NewMouse & MOUSE_INPUT_LEFT) { SendMessage(GetMainWindowHandle(), WM_NCLBUTTONDOWN, HTCAPTION, 0); } OldMouse = NewMouse; ClearDrawScreen( ); DrawFormatString( 0, 0, white, "TEST" ); DrawBox( 100, 100, 200, 200, white, TRUE ); ScreenFlip( ); } DxLib_End( ); return 0; }
Re: 実行画面を上に移動して固定したい ( No.8 )
名前:s707 日時:2012/02/10 01:40

いっち様、迅速な対応ありがとうございます。 テストコードは成功しました。 後はコードを合体させてみます。 SetHookWinProc関数が便利ですね。
Re: 実行画面を上に移動して固定したい ( No.9 )
名前:s707(解決) 日時:2012/02/10 02:26

いっち様、おかげさまで解決しました。 中々進展しなかったので嬉しいです。 まさか1日で解決するとは思いませんでした。 本当にありがとうございます。 いい夢見れそうです。
Re: 実行画面を上に移動して固定したい ( No.10 )
名前:いっち 日時:2012/02/11 15:34

管理人さん> SetHookWinProc で設定されたウィンドウプロシージャはDXライブラリのウィンドウプロシージャの中で実行されていますが、 戻り値が無視されているようなので、以下のようにメッセージの処理結果としてシステムに特定の値を返却するような処理は うまくいかないと思います。 > case WM_NCHITTEST: > return HTCAPTION; そこで要望なのですが「SetHookWinProc で設定したウィンドウプロシージャの実行後、DXライブラリの処理を継続するか、 即座にシステムに戻り値を返すかを選択する機構」を実装して頂くことは可能でしょうか? 例えば・・・ 1) SetHookWinProcContinueFlag( int Flag ) のような関数を自前のウィンドウプロシージャの中で呼び出して動作を設定する 2) フラグを返却するための引数を追加したウィンドウプロシージャを自前のプロシージャとして設定できるようにする ・・・といったような感じで実装して頂けると助かります。(もちろん他に案があればその様になさってください) それと SetUserWindow との兼ね合いはどのようになっているのかと思い少し試してみたのですが、 > h t t p ://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1556 > 因みに SetUserWindow に渡したウインドウのメッセージ処理はDXライブラリでは行われませんので、 > 自前でメッセージ処理を行う必要があります と、あるようにDXライブラリのウィンドウプロシージャ(DxLib_WinProc)が実行されないのは仕様なのでしょうか? DxLib_WinProc の中では以下のように元々のウィンドウプロシージャを呼ぶような処理が見受けられます。 (SetWindowLong でウィンドウプロシージャを入れ替えるような処理は無いのでデッドコードなのだとは思います) > // ユーザーから提供されたウインドウを使用している場合はそのウインドウのプロシージャを呼ぶ > if( WinData.UserWindowFlag == TRUE ) > { > if( WinData.DefaultUserWindowProc != NULL ) > { > UserProcRet = WinData.DefaultUserWindowProc( hWnd, message, wParam, lParam ) ; > } > } 余談ですが、ビルド環境が VS2010 に変わったのでしょうか? VS2008 ではソリューションが開けませんでした。
Re: 実行画面を上に移動して固定したい ( No.11 )
名前:管理人 日時:2012/02/13 01:42

SetHookWinProc で設定できるプロージャの戻り値については仕様を少し考えてみます SetUserWindow ではDXライブラリのウインドウプロージャが実行されないのは仕様です 「DXライブラリのプロージャを実行したいような場合は、そもそも独自のウインドウに する必要がないんじゃないか?」と思って中途半端な実装になっているのだと思います ( とはいえ実装したのはかなり昔なので記憶はなく、あくまで推測ですが・・・ ) 因みに、個人的にはDXライブラリの処理と競合して動作が破綻する確率が高くなるので SetHookWinProc や SetUserWindow はなるべく使われない方が良いなと思っています (- -; > 余談ですが、ビルド環境が VS2010 に変わったのでしょうか? > VS2008 ではソリューションが開けませんでした。 どのソリューションでしょうか?
Re: 実行画面を上に移動して固定したい ( No.12 )
名前:いっち 日時:2012/02/15 22:11

回答ありがとうございます。散漫な内容になってしまってすみません。 > SetHookWinProc で設定できるプロージャの戻り値については仕様を少し考えてみます 了解しました。よろしくお願いします。 絶対無理だろうなと思ったので書かなかったのですが、個人的に最もスマートな対策だと思っているのは 「SetHookWinProc で渡されたプロシージャを DxLib_WinProc の中で DefWindowProc の代わりに使用する」 というものです。(互換性がとれないですよね・・・) > SetUserWindow ではDXライブラリのウインドウプロージャが実行されないのは仕様です 了解しました。 > 因みに、個人的にはDXライブラリの処理と競合して動作が破綻する確率が高くなるので > SetHookWinProc や SetUserWindow はなるべく使われない方が良いなと思っています (- -; 私もその様に思いますが、スクリーンセーバーのような用途もあるようですし、 「出来ない」と「出来る場合もある」ではだいぶ違いますのであると助かる人は多いのではないかと思います。 > > 余談ですが、ビルド環境が VS2010 に変わったのでしょうか? > > VS2008 ではソリューションが開けませんでした。 > どのソリューションでしょうか? h t t p ://dxlib.o.oo7.jp/DxLib/DxLibMake3_07a.exe に同梱されている DxLibMake.sln です。 DxLibMake.vcproj から変換した場合もそのままではコンパイルには失敗するようでした。
Re: 実行画面を上に移動して固定したい ( No.13 )
名前:管理人 日時:2012/02/19 13:06

> 1) SetHookWinProcContinueFlag( int Flag ) のような関数を自前のウィンドウプロシージャの中で呼び出して動作を設定する こちらの案に近いものにしました // SetHookWinProc で設定したウインドウプロージャの戻り値を使用するかどうかを設定する // SetHookWinProc で設定したウインドウプロージャの中でのみ使用可能 // ( int UseFlag //  TRUE:戻り値を使用して、DXライブラリのウインドウプロージャの処理は行わない //  FALSE:戻り値は使用せず、ウインドウプロージャから出た後、DXライブラリのウインドウプロージャの処理を行う ) int SetUseHookWinProcReturnValue( int UseFlag ) ; ウインドウプロージャの中で使います > case WM_NCHITTEST: > return HTCAPTION; この場合は > case WM_NCHITTEST: > SetUseHookWinProcReturnValue( TRUE ) ; > return HTCAPTION; このようにして使用します 上記の関数を追加したバージョンはこちらにアップしました http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibGCCTest.exe // Dev-C++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMinGWTest.exe // MinGW 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) > h t t p ://dxlib.o.oo7.jp/DxLib/DxLibMake3_07a.exe に同梱されている DxLibMake.sln です。 > DxLibMake.vcproj から変換した場合もそのままではコンパイルには失敗するようでした。 DxLibMake のプロジェクトは VisualStudio2010 にしました 気を抜くとすぐ新バージョンが出て古いバージョンのプロジェクトファイルになってしまうので、 少し整理したときに暫く手入れをせずに済むように VisualStudio2010 のプロジェクトファイルにしました
Re: 実行画面を上に移動して固定したい ( No.14 )
名前:いっち 日時:2012/02/19 18:38

お疲れ様です。 意図通り動作することを確認しました。 対応ありがとうございました。 > int SetUseHookWinProcReturnValue( int UseFlag ) ; 若干補足させて頂きますと、上記関数はウィンドウプロシージャが呼ばれるたびにデフォルト値(FALSE)にリセットされます。 ですので、実質的に SetUseHookWinProcReturnValue( FALSE ) として呼び出す必要はありません。 逆に TRUE に設定したい場合は毎回呼び出す必要があります。 > DxLibMake のプロジェクトは VisualStudio2010 にしました > 気を抜くとすぐ新バージョンが出て古いバージョンのプロジェクトファイルになってしまうので、 > 少し整理したときに暫く手入れをせずに済むように VisualStudio2010 のプロジェクトファイルにしました なるほど、了解しました。

Page: 1 |