WM_LBUTTONUPメッセージについて


Cの使用者  2004-12-13 01:28:43  No: 55647

すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。


なーめ  2004-12-13 01:55:12  No: 55648

MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。


Cの使用者  2004-12-13 07:39:21  No: 55649

あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。


Cの使用者  2004-12-13 07:49:55  No: 55650

すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?


なーめ  2004-12-13 11:45:14  No: 55651

ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
  switch( msg )
  {
    case WM_MBUTTONDOWN:
      tr("RichEdit::MButtonDown().\n");
      break;
    case WM_MBUTTONUP:
      tr("RichEdit::MButtonUp().\n");
      break;
    case WM_RBUTTONDOWN:
      tr("RichEdit::RButtonDown().\n");
      break;
    case WM_RBUTTONUP:
      tr("RichEdit::RButtonUp().\n");
      break;
    case WM_LBUTTONDOWN:
      tr("RichEdit::LButtonDown().\n");
      break;
    case WM_LBUTTONUP:
      tr("RichEdit::LButtonUp().\n");
      break;
  }
  return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
  va_list args;
  va_start(args, lpszFormat);
  int nBuf;
  TCHAR szBuffer[8192];
  nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
  OutputDebugString( szBuffer );
  va_end(args);
}


na-me  2004-12-13 11:50:52  No: 55652

Win2K,VC++6.0ですが。


なーめ  2004-12-13 11:54:31  No: 55653

仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm


なーめ  2004-12-13 12:32:33  No: 55654

>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。


Cの使用者  2004-12-13 19:14:06  No: 55655

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。


なーめ  2004-12-13 21:47:55  No: 55656

メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
  UINT msg;
  char * name;
}
g_msgStrs[] =
{
  { WM_NULL,          "WM_NULL"            },
  { WM_CREATE,        "WM_CREATE"            },
  { WM_DESTROY,        "WM_DESTROY"          },
  .....
  { WM_MOUSEMOVE,        "WM_MOUSEMOVE"          },  //  0x0200
  { WM_LBUTTONDOWN,      "WM_LBUTTONDOWN"        },  //  0x0201
  { WM_LBUTTONUP,        "WM_LBUTTONUP"          },  //  0x0202
  { WM_LBUTTONDBLCLK,      "WM_LBUTTONDBLCLK"        },  //  0x0203
  .....
};

char * strmsg( UINT msg )
{
  int c;
  static char s[128];
  for( c = 0; g_msgStrs[c].name; c ++ )
  {
    if( g_msgStrs[c].msg == msg )
    {
      return( g_msgStrs[c].name );
    }
  }
  sprintf( s,"unknown[%08X]", msg );
  return( s );
}


なーめ  2004-12-13 22:12:53  No: 55657

...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN


Cの使用者  2004-12-13 22:54:29  No: 55658

RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。


なーめ  2004-12-14 00:36:36  No: 55659

>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?


Cの使用者  2004-12-14 04:47:19  No: 55660

しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?


なーめ  2004-12-14 07:12:08  No: 55661

>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?


Cの使用者  2004-12-14 07:14:49  No: 55662

もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?


なーめ  2004-12-14 07:27:52  No: 55663

>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。


Cの使用者  2004-12-15 05:33:41  No: 55664

すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?


なーめ  2004-12-15 07:51:14  No: 55665

>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。


RAPT  2004-12-15 10:06:04  No: 55666

OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html


Cの使用者  2004-12-16 03:55:38  No: 55667

デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?


なーめ  2004-12-16 09:04:21  No: 55668

あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
  //  return( WinMain2( hInst, hPrev, line, show ));
  if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
  {
    tr("ライブラリのロード失敗");
    return( -1 );
  }
  // 本体プログラム
  // .......
  if( FreeLibrary( g_hRtLib ) == 0 )
  {
    tr("ライブラリ解放失敗.\n");
  }
  return 0;
}


Cの使用者  2004-12-18 02:34:31  No: 55669

ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。


eefe  2004-12-19 02:33:28  No: 55670

--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの


edd  2004-12-19 02:34:37  No: 55671

WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------


yjyjy  2004-12-19 02:35:26  No: 55672

WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------


rrgr  2004-12-19 02:35:44  No: 55673

WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------


thtt  2004-12-19 02:35:58  No: 55674

WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------


svdav  2004-12-19 02:43:49  No: 55675

string型の==での比較について
[戻る] 
--------------------------------------------------------------------------------
かぷ 2004/12/16(木) 17:07:12
if (strChar.c_str() == "内容") {
    省略
}

この場合でstrCharに「内容」が入っていても
通過してしまうのですが何か良い方法はありませんか?

よろしくお願いします。

--------------------------------------------------------------------------------
tetrapod 2004/12/16(木) 17:27:55
提示コードがうまく動くわけが無い、ことが判らないようなら、
C なり C++ なりの基本をもっと勉強するべきでしょう。

単純に str=="内容" でいい。

--------------------------------------------------------------------------------
Blue 2004/12/18(土) 02:14:41
過去ログ参照してみて。。。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgiprint+200411/04110045.txt

string型ていってるのが、std::stringであればそれらしいメソッドがあります。

--------------------------------------------------------------------------------
B 2004/12/18(土) 02:23:42
リンク先の?が抜けてました。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200412/04120051.txt

--------------------------------------------------------------------------------
bhthbt 2004/12/18(土) 17:31:56
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
tht 2004/12/18(土) 17:36:37
WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
hhtt 2004/12/18(土) 17:36:53
WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
ttrsj 2004/12/18(土) 17:37:07
WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
     case WM_LBUTTONDOWN:
          MessageBox(hwnd,"","",MB_OK);
          break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

はちゃんとメッセージボックスが2つでるのですが、

LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){
 //    case WM_LBUTTONDOWN:
 //         MessageBox(hwnd,"","",MB_OK);
 //         break;
     case WM_LBUTTONUP:
          MessageBOx(hwnd,"","",MB_OK);
          break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp )); 
}

こちらはウンともスンとも言いません。
選択範囲をポイントするとマウスカーソルが矢印に変わりますよね(RichEditの場合)。
そのときは後者のプログラムも反応するのですが・・・。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 12:47:55
メッセージボックスを使っているのですか。
メッセージボックスは Focus を変えてしまうので、
予期せぬメッセージが飛び交います。
VCのデバッグモードで、tr() を使ってメッセージを
確認してください。spy++ を使ってもいいです。
確認とはメッセージの意味をHELPで調べるということです。

WM_LBUTTONUP でのメッセージボックスは関係ないように
思われるかもしれませんが、次の WM_LBUTTONDOWN が発生するときに
FOCUS の変化のためのメッセージが飛んできて、面倒なことになります。

このような障害を相手にするときは、注目しているメッセージだけでなく、
他のすべtのメッセージを表示させるようにすべきです。
何が起きているか、間接的にでもつかめることが多いというものです。

そして、WM_SETCURSOR とか WM_MOUSEMOVE のような
分かりきったものを表示からはずしてゆけばいいですね。
たまに、外したものが重要なメッセージであったこともありますが。(^^;;
メッセージのコードをいちいち調べるのが面倒なら、
以下の文字列化テーブルとルーチンを用意しておきましょう。
一度だけ我慢して作っておけば、再利用可能ですからね。
もちろん全てのメッセージを網羅しておかないと、意味ないです。

struct tagMsgStrs
{
    UINT msg;
    char * name;
}
g_msgStrs[] =
{
    { WM_NULL,                    "WM_NULL"                        },
    { WM_CREATE,                "WM_CREATE"                        },
    { WM_DESTROY,                "WM_DESTROY"                    },
    .....
    { WM_MOUSEMOVE,                "WM_MOUSEMOVE"                    },    //    0x0200
    { WM_LBUTTONDOWN,            "WM_LBUTTONDOWN"                },    //    0x0201
    { WM_LBUTTONUP,                "WM_LBUTTONUP"                    },    //    0x0202
    { WM_LBUTTONDBLCLK,            "WM_LBUTTONDBLCLK"                },    //    0x0203
    .....
};

char * strmsg( UINT msg )
{
    int c;
    static char s[128];
    for( c = 0; g_msgStrs[c].name; c ++ )
    {
        if( g_msgStrs[c].msg == msg )
        {
            return( g_msgStrs[c].name );
        }
    }
    sprintf( s,"unknown[%08X]", msg );
    return( s );
}

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 13:12:53
...にしても、示された部分について
まったくあなたと同じコードにしてみたら、
WM_LBUTTONUP のダイアログは必ず表示されますが。
やっぱり OS が違うのか。開発環境が違うのか。
ちなみ RichEdit のスタイルは次のようにしています。

WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 13:54:29
RichEditは  http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm  のやり方を使わせていただいているのですが、どうもフォントを初期化している関数で処理の流れが変わっているようです。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 15:36:36
>> <URL> のやり方を使わせていただいているのです
私もトレースを簡単に行なおうと思い、一部、これをコピーしています。

>> どうもフォントを初期化している関数で処理の流れが変わっているようです
なので、フォントの部分は同じコーディングになっています。
でも WM_LBUTTONUP は正常に来ていますよ。

そもそも、EM_SETCHARFORMATが関係しているとは
考えにくいですが、WM_LBUTTONDONW-WM_LBUTTONUP の間に
このメッセージが飛んでくるなら話は別ですが。

tr() を使ってメッセージ表示してみましたか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 19:47:19
しかし、SetInitialFont(HWND hWnd);(フォントの初期化の部分)を実行させないようにすれば、WM_LBUTTONUPメッセージが単独でもきちんと来るようになりますよ。
関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:12:08
>> 関係ないのでしょうか?
私のところでその状況を再現できるようにするにはどうしたら
いいですか?

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 22:14:49
もしかして環境依存のほうでしょうか?
私はBorland C++ を使っているのですが、そういうことは関係ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 22:27:52
>> Borland C++
それを早く言ってくださいよ。
私には全く同じ環境での確認できません。
ただ、メッセージの流れについて見ることは
判断できそうですが、
tr() または OutputDebugString() を
使うことは不可能なのでしょうか?
最後の手段としては WinMain() でログファイルを
開いて(作成して)そこに記録するという方法も考えられますが。

VC++ じゃないから Spy++ といわれても
何のことかさっぱりだったでしょうね。

--------------------------------------------------------------------------------
Cの使用者 2004/12/14(火) 20:33:41
すいません。これからは環境を明記するようにします。

ところで、Visual C++の場合、OutputDebugString()はどうやって使うのですか?
あと SPY++のようなプログラムをご存じでしたら教えてくださいませんか?

--------------------------------------------------------------------------------
なーめ 2004/12/14(火) 22:51:14
>> OutputDebugString()はどうやって使うのですか?
上に私のtr() があるでしょう。
使用例そのものですよ。

VC++ のデバッグモードで F5 押して起動。
OutputDebugString() で出力した文字列はすべて VC++ のデバッグ窓に
出力されます。VC++ でなくてもこの文字列を出力するツールがあるようです。
他の質問のところに書いてあった記憶が...。
Spy++ は全てのウィンドウを一覧表示し、そのなかから特定のウィンドウを
選択してそこにやってくるメッセージをモニタするものです。
VC++ をインストールすると入っているのですが。

--------------------------------------------------------------------------------
RAPT 2004/12/15(水) 01:06:04
OutputDebugString はAPIです。
APIなので、VC++以外でも使えると思います。

DbgMOn とか。
http://www.vector.co.jp/soft/win95/prog/se169346.html

--------------------------------------------------------------------------------
Cの使用者 2004/12/15(水) 18:55:38
デバッガでトレースする限りでは、プログラムが終了するときにRichEdit関係のエラーがおこっているようですが、RichEditはメインウィンドウ以外(たとえばTabコントロールなど)を親とすることは出来ないのでしょうか?

--------------------------------------------------------------------------------
なーめ 2004/12/16(木) 00:04:21
あ、私のところでも終了時のエラーはありましたが、
『猫でも』の方法でよくないと思われることがあります。
LoadLibrary("RICHED32.DLL");
FreeLibrary(hRtLib);
の位置なのですが、
これを WinMain() の最初と最後に移動してみてください。

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int show)
{
    //    return( WinMain2( hInst, hPrev, line, show ));
    if(( g_hRtLib = LoadLibrary("RICHED32.DLL")) == NULL )
    {
        tr("ライブラリのロード失敗");
        return( -1 );
    }
    // 本体プログラム
    // .......
    if( FreeLibrary( g_hRtLib ) == 0 )
    {
        tr("ライブラリ解放失敗.\n");
    }
    return 0;
}

--------------------------------------------------------------------------------
Cの使用者 2004/12/17(金) 17:34:31
ほかのサイトを探してみたところ、WM_NOTIFY メッセージを使ってやりたかったことを実現できましたが、そもそもRichEditは、「マウスでドラッグする」等の作業をするとき WM_LBUTTONUPメッセージは出るのですか?
Editでは出ていたのですが・・・。

--------------------------------------------------------------------------------
eefe 2004/12/18(土) 17:33:28
--------------------------------------------------------------------------------
  Elfaria Development Studio.eds  (EDS) 

--------------------------------------------------------------------------------

VB.NET / C# / Mono / Linux についてのTips等を公開しています。 
また、少しですがコラムも公開しています。

--------------------------------------------------------------------------------
  Programming Library 

--------------------------------------------------------------------------------

主にVB,VC等の各言語に関するテクニックやAPI情報を掲載しております。 
その他としまして掲示板にて情報交換の場を設けています。 
当サイトの趣旨は「情報共有」で、より技術向上の場として自分達運営者を含め、開発者達のお役に立てればと思い運営しております。

--------------------------------------------------------------------------------
>> このページのTOPへ   

--------------------------------------------------------------------------------
  猫でもわかるプログラミング  (猫プロ) 

--------------------------------------------------------------------------------

超初心者対象のC/C++講座です。ともかくわかりやすく、初心者に優しいをモットーに運営しています。スマートなプログラムより、わかりやすいプログラムを目指しています。

--------------------------------------------------------------------------------
  らららのプログラマーズラウンジ 

--------------------------------------------------------------------------------

らららの

--------------------------------------------------------------------------------
追加発言 
■ お名前(ペンネーム可)
    
■ メールアドレス(省略可、半角で入力)
    
■ ホームページアドレス(省略可、半角で入力)
    
■ 発言(エラー時再送信禁止)
    ←解決時は質問者本人がここをチェックしてください。
    
      

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
thts 2004/12/18(土) 17:37:20
WM_LBUTTONUPメッセージについて
[戻る] 
--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 16:28:43
すいません。また質問です。
サブクラス化で詰まってしまいました。
WNDPROC Org_EditProc;

Org_EditProc=(WNDPROC)SetWindowLong(hEdit,GWL_WNDPROC,(LONG)EditProc);
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wp,LPARAM  lp)
{
switch(msg){

    ・
    ・
と書いたら、WM_LBUTTONUPメッセージがうまく届かないのですが、なぜかわかりません。どなたか教えてください。

--------------------------------------------------------------------------------
なーめ 2004/12/12(日) 16:55:12
MFCで OnLButtonDown を実装すると、
正しく呼ばれるので、Editコントロールの
問題ではないですね。
(MFCは AfxWinProc という関数でサブクラス化しています)

CStatic でスクロールバーが制御できないのとは別のようです。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200410/04100062.txt
では、WM_LBUTTONDOWN はどこへ行ってしまうのか。
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200411/04110069.txt
において、WM_DROPFILES が行方不明になるのを解決した例が
ある(一番最後の私の発言)ので、参考まで。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:39:21
あの、WM_LBUTTONDOWN メッセージを採った直後ならWM_LBTTONUPメッセージを取れるのですが、何か関係があるのでしょうか? 

それと、MFCに関する知識がまったく無いので、出来ればSDKだけでお願いします。

--------------------------------------------------------------------------------
Cの使用者 2004/12/12(日) 22:49:55
すいません。大変重大なことに気づきました。

最初はそれほど重大なこととは思っていなかったのですが、Editでは無く、RichEditでした。
RichEditを作成していたところでEditを作成するようにプログラムを変更してみたところ、うまく動作しました。

RichEditはEditを拡張して作ったものだと思っていたのですが、RichEditでWM_LBUTTONUPに相当するメッセージを受けるにはどうすればいいのですか?

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:45:14
ちゃんと呼ばれますよ。WM_LBUTTONUP。

LRESULT CALLBACK RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp)
{
    switch( msg )
    {
        case WM_MBUTTONDOWN:
            tr("RichEdit::MButtonDown().\n");
            break;
        case WM_MBUTTONUP:
            tr("RichEdit::MButtonUp().\n");
            break;
        case WM_RBUTTONDOWN:
            tr("RichEdit::RButtonDown().\n");
            break;
        case WM_RBUTTONUP:
            tr("RichEdit::RButtonUp().\n");
            break;
        case WM_LBUTTONDOWN:
            tr("RichEdit::LButtonDown().\n");
            break;
        case WM_LBUTTONUP:
            tr("RichEdit::LButtonUp().\n");
            break;
    }
    return( CallWindowProc( g_prgRichOrgProc,hTab,msg,wp,lp ));
}

-------------- output -------------
RichEdit::RButtonDown().
RichEdit::RButtonUp().
RichEdit::LButtonDown().
RichEdit::LButtonUp().
RichEdit::MButtonDown().
RichEdit::MButtonUp().

ちなみに、tr() は以下のルーチン。printf系書式対応。

#include <stdio.h>

void tr( LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[8192];
    nBuf = _vsntprintf(szBuffer, sizeof(szBuffer), lpszFormat, args);
    OutputDebugString( szBuffer );
    va_end(args);
}

--------------------------------------------------------------------------------
na-me 2004/12/13(月) 02:50:52
Win2K,VC++6.0ですが。

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 02:54:31
仮名漢字変換になってなかったので Enter で送信されてしまった。
失礼。
こちらは、Win2K,VC++6.0ですが。
OS/Libraryの違いにより微妙に動作が違うことがあるかもしれません。
参考まで:
http://www.kumei.ne.jp/c_lang/sdk2/sdk_130.htm

--------------------------------------------------------------------------------
なーめ 2004/12/13(月) 03:32:33
>> WM_LBUTTONDOWN メッセージを採った直後なら
>> WM_LBTTONUPメッセージを取れるのですが

単に、WM_LBUTTONUPが来ないというわけではないのでしたね。
WM_LBUTTONDOWN を取ったあと、処理に時間がかかるということでしょうか。
単純に WM_LBUTTONDOWN の処理で、Sleep(10000) して見ましたが、
やはり変わりません(WM_LBUTTONUPは来ます)。

メッセージキューをスキップしてしまうような処理が間に挿入されている
のではないでしょうか。

ためしに、Sleep(1000); の状態で、RichEditコントロールを
クリック、すぐに押したままウィンドウ外でボタンを放しました。
すると、WM_LBUTTONUPはきませんね。
この操作でやってくるメッセージを眺めると、

WM_PAINT
WM_ERASEBKGND
WM_MOUSEMOVE
WM_CAPTURECHANGED

が来ていました。
最後のが妖しいですね。
マウスがキャプチャされたらしいです。

上記の、RichProc(HWND hTab, UINT msg, WPARAM wp, LPARAM lp) に

  default:
    tr("msg: %08X.\n", msg );
    break;

を加えての調査です。
WM_LBUTTONUPが来ないときにどのようなメッセージがきているか
そちらでも調査してみるとよいでしょう。

--------------------------------------------------------------------------------
Cの使用者 2004/12/13(月) 10:14:06
LRESULT CALLBACK EditProc(HWND hwnd, UINT msg,


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加