こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Win32APIにて、ウィンドウ全体をドラッグして動かしたいのですが。

こんにちは。
いつもお世話になっております。

小生、只今WindowsXPSP3上で、C言語とWin32APIを使用し、BCC5.5.1でコンパイルしながら、Windowsプログラミングを勉強しています。

度々、質問させて頂き、その都度回答を頂戴し、誠に恐縮ではあるのですが、今回も質問させて下さい。

下記のコードをコンパイルすると、タイトルバーをドラッグして移動する事は出来るのですが、ウィンドウ全体(クライアント領域も含めて)移動するにはどのようにすればいいのでしょうか??

/* ウィンドウ表示 */
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE, LPCSTR);
BOOL InitInstance(HINSTANCE, int, LPCSTR);

int WINAPI WinMain(
HINSTANCE hCurInst,
HINSTANCE hPrevInst,
LPSTR lpsCmdLine,
int nCmdShow)
{
MSG msg;
BOOL bRet;
LPCSTR szClassName = "Window";

if(!InitApp(hCurInst, szClassName)){
return FALSE;
}

if(!InitInstance(hCurInst, nCmdShow, szClassName)){
return FALSE;
}

while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
if(bRet == -1){
MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
break;
}
else{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
WNDCLASSEX wc;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(
NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = (LPCSTR)szClassName;
wc.hIconSm = (HICON)LoadImage(
NULL,
MAKEINTRESOURCE(IDI_APPLICATION),
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);

return (RegisterClassEx(&wc));
}

//ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName)
{
HWND hWnd;

hWnd = CreateWindow(
szClassName,
"Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
200,
NULL,
NULL,
hInst,
NULL);

if(!hWnd){
return FALSE;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

return TRUE;
}

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch(msg){
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}

return 0;
}

お忙しい中申し訳ございませんが、
先輩方、アドバイス宜しくお願い致します。

投稿日時 - 2010-03-06 02:26:01

QNo.5728509

すぐに回答ほしいです

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

#3です。

すみません。#3で紹介したサイトの情報を良く見ていませんでした。

#3のコードだと、クライアント領域上でダブルクリックすると、「最大化」、または、
「元のサイズに戻す」の動作が実行されてしまいますね。
(これはこれで、面白い動作ですが。。。)

ですので、これで支障がある場合は、同サイトの【方法2】の方法を採った方が、
良いと思います。

以下は、【方法2】のコード例です。
ウィンドウプロシージャ「WndProc」の部分のみ掲載致します。

■改造ソース(その2)
注)インデント等のため、全角スペースを入れています。
  ご使用の際は、半角スペースorタブに置換して下さい。

/////↓ここから///////////////////////////////////
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
//  UINT nRes;

  //メッセージ処理
  switch(msg)
  {
//////こちらは使用しない///////////
//  //マウス移動のメッセージ処理
//  case WM_NCHITTEST:
//    //クライアント領域だった場合は、タイトルバー上での動作と
//    //同じ動作を行わせる
//    nRes = DefWindowProc(hWnd, msg, wp, lp);
//    if (nRes == HTCLIENT) nRes = HTCAPTION;
//    return nRes;
////////////////////////////////

  //マウスの左ボタン押下時の処理
  case WM_LBUTTONDOWN:
    //クライアント領域だった場合でも、タイトルバーでクリック
    //されたことにしてメッセージ送信
    PostMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, lp);
    break;

  //プログラム終了時のウインドウ破棄
  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return (DefWindowProc(hWnd, msg, wp, lp));
  }

  return 0;
}
/////↑ここまで///////////////////////////////////

以上です。

投稿日時 - 2010-03-06 15:26:58

お礼

ご回答頂き誠にありがとうございます。

提示して頂いたコードをコンパイルし、実行してみると、
見事、クライアント領域をドラッグしてウィンドウを移動させる事が出来ました!!

しかも、サイトのURLまで掲載して頂いて。。。

誠に感謝申し上げあげます。

投稿日時 - 2010-03-06 19:21:46

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(4)

こんにちは。

> タイトルバーをドラッグして移動する事は出来るのですが、ウィンドウ全体
> (クライアント領域も含めて)移動するにはどのようにすればいいのでしょうか?

最初、上記の意味がよく解らなかったのですが、
#1さんの回答を見て、

  『クライアント領域で、マウスドラッグされた場合でも、
  タイトルバー上で、マウスドラッグされた場合と同様に、
  ウィンドウ全体を移動させたい。』

という意味だと理解できました。

方法は、#1さんの方法で対処可能だと思います。

ただし、#1さんが紹介されたリンク先サイトのやり方は、
  タイトルバーが無いウィンドウアプリ
での方法ですので、それをそのまま、
  タイトルバーが有るウィンドウアプリ
で使用すると、
タイトルバーの「システムコマンド」(最小化、最大化、閉じる、など)
の処理が機能しなくなってしまうようです。

それを回避するには、下記サイトの方法で対処可能だと思います。

◎タイトルバー以外の部分をドラッグしてウィンドウを移動させる
http://hp.vector.co.jp/authors/VA023539/tips/window/005.htm

参考までに、上記サイトの方法を、ご提示のソースに加味したソース
を掲載致します。
宜しければ、試してみて下さい。

■改造版ソース
注)インデント等のため、全角スペースを入れています。
  ご使用の際は、半角スペースorタブに置換して下さい。

/////↓ここから///////////////////////////////////
/* ウィンドウ表示(改造版)*/
#include <windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE, LPCSTR);
BOOL InitInstance(HINSTANCE, int, LPCSTR);

//WinMain
int WINAPI WinMain(
    HINSTANCE hCurInst,
    HINSTANCE hPrevInst,
    LPSTR lpsCmdLine,
    int nCmdShow)
{
  MSG msg;
  BOOL bRet;
  LPCSTR szClassName = "Window";

  if(!InitApp(hCurInst, szClassName)){
    return FALSE;
  }

  if(!InitInstance(hCurInst, nCmdShow, szClassName)){
    return FALSE;
  }

  while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){
    if(bRet == -1){
      MessageBox(NULL, "GetMessage Error", "Error", MB_OK);
      break;
    }
    else{
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }

  return (int)msg.wParam;
}

//ウィンドウクラスの登録
ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName)
{
  WNDCLASSEX wc;

  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = WndProc;
  wc.cbClsExtra = 0;
  wc.cbWndExtra = 0;
  wc.hInstance = hInst;
  wc.hIcon = (HICON)LoadImage(
      NULL,
      MAKEINTRESOURCE(IDI_APPLICATION),
      IMAGE_ICON,
      0,
      0,
      LR_DEFAULTSIZE | LR_SHARED);
  wc.hCursor = (HCURSOR)LoadImage(
      NULL,
      MAKEINTRESOURCE(IDC_ARROW),
      IMAGE_CURSOR,
      0,
      0,
      LR_DEFAULTSIZE | LR_SHARED);
  wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
  wc.lpszMenuName = NULL;
  wc.lpszClassName = (LPCSTR)szClassName;
  wc.hIconSm = (HICON)LoadImage(
      NULL,
      MAKEINTRESOURCE(IDI_APPLICATION),
      IMAGE_ICON,
      0,
      0,
      LR_DEFAULTSIZE | LR_SHARED);

  return (RegisterClassEx(&wc));
}

//ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName)
{
  HWND hWnd;

  hWnd = CreateWindow(
      szClassName,
      "Window",
      WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT,
      CW_USEDEFAULT,
      200,
      200,
      NULL,
      NULL,
      hInst,
      NULL);

  if(!hWnd){
    return FALSE;
  }

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  return TRUE;
}

//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
  UINT nRes;

  //メッセージ処理
  switch(msg)
  {
  //マウス移動のメッセージ処理
  case WM_NCHITTEST:
    //クライアント領域だった場合は、タイトルバー上での動作と
    //同じ動作を行わせる
    nRes = DefWindowProc(hWnd, msg, wp, lp);
    if (nRes == HTCLIENT) nRes = HTCAPTION;
    return nRes;

  //プログラム終了時のウインドウ破棄
  case WM_DESTROY:
    PostQuitMessage(0);
    break;

  default:
    return (DefWindowProc(hWnd, msg, wp, lp));
  }

  return 0;
}
/////↑ここまで///////////////////////////////////

以上です。参考になれば幸いです。

投稿日時 - 2010-03-06 14:03:11

補足

ご回答頂き、ありがとうございます。

>> タイトルバーをドラッグして移動する事は出来るのですが、ウィンドウ全体
>> (クライアント領域も含めて)移動するにはどのようにすればいいのでしょうか?

>最初、上記の意味がよく解らなかったのですが、

よく意味の分からない質問内容を記述してしまい、
申し訳ございません。

これからは、よく考え、何度も読み直して質問したいと思います。
ご教授ありがとうございました。

投稿日時 - 2010-03-06 19:22:20

ANo.2

>ウィンドウ全体(クライアント領域も含めて)移動するには
>どのようにすればいいのでしょうか??
[ALT]キーを押しながらドラッグすればできますが...
それでは駄目なのでしょうか?

投稿日時 - 2010-03-06 07:46:39

お礼

ご回答頂き、ありがとうございます。

>[ALT]キーを押しながらドラッグすればできますが...
>それでは駄目なのでしょうか?

どうしても、マウスでドラッグしたいのです。
ですが、[ALT]キー押下しながらでドラッグ出来るのは知りませんでした!

誠に感謝申し上げます。

投稿日時 - 2010-03-06 19:13:49

ANo.1

Wr5

>タイトルバーをドラッグして移動する事は出来るのですが、ウィンドウ全体(クライアント領域も含めて)移動するにはどのようにすればいいのでしょうか??

クライアント上に他のコントロールなどが乗っている場合は、また違いますが…
WM_NCHITTESTの応答で可能です。
# http://win32lab.com/tips/tips17.html

ただし……クライアント領域をタイトルバーと同等の扱いをすることになりますので、
他で不具合があるかも知れません。

投稿日時 - 2010-03-06 02:40:38

お礼

ご回答頂き誠にありがとうございます。

提示していただいた、サイトをこれからも参考に勉強したいと思います。

誠に感謝申し上げます。

投稿日時 - 2010-03-06 19:11:43

あなたにオススメの質問