リストビューでNM_CLICKを受け取った時のINDEX取得

このQ&Aのポイント
  • VC++6.0 SDKのLISTVIEWでNM_CLICKを受け取った時のINDEXを取得する方法を教えてください。
  • 現在のソースではインデントが無効になってしまい、見やすくないので修正したいです。
  • クリックした位置の名前とチェック状態を取得し、INIファイルに書き込む処理を行っています。
回答を見る
  • ベストアンサー

リストビューでNM_CLICKを受け取った時のINDEX取得

VC++6.0 SDKでLISTVIEWでNM_CLICKを受け取った時のINDEXを取得したいのですがどうしたらよいのでしょう? 以下現在のソースです、インデントが無効になってしまい、見にくくてすみません。 case WM_NOTIFY: if((int)wp == IDLV_OPT_YAMAHA){ lvinfo = (LV_DISPINFO *)lp; switch (lvinfo->hdr.code){ case NM_CLICK: //click位置の名前とcheck GetCursorPos(&pt); //hittest.pt = pt; iIndex = LBItemFromPt(GetDlgItem(ghWnd, IDLV_OPT_YAMAHA), pt, FALSE); if(iIndex != -1){ ListView_GetItemText(GetDlgItem(ghWnd, IDLV_OPT_YAMAHA), iIndex, 0, szMcn, sizeof(szMcn)); fState = ListView_GetCheckState(GetDlgItem(ghWnd, IDLV_OPT_YAMAHA), iIndex); if(fState){ WritePrivateProfileString("CONNECT", szMcn, "1", PATH_INI); sprintf(gszDebug, "%s 1", szMcn); MessageBox(NULL, gszDebug, "error", MB_OK); }else { WritePrivateProfileString("CONNECT", szMcn, "0", PATH_INI); sprintf(gszDebug, "%s 0", szMcn); MessageBox(NULL, gszDebug, "error", MB_OK); } } break; } } break;

  • yruri
  • お礼率40% (21/52)

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

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.4

>Spy++試してみます。 >なんかおもしろそうなソフトですけど、よく使われるものなんでしょうか? ウィンドウの情報を得るんでしたら必須ですね。ぜひ使いこなしてください。 これを使えば表示、非表示にかかわらずすべての起動中のウィンドウに対して調査を行うことが出来ます。 よく使うところですとウィンドウメッセージの受信内容の取得やウィンドウクラス名の取得、ダイアログのコントロールIDの確認なんかですかね。 取得可能な情報はこれだけじゃなく、ウィンドウに関する情報はほぼ全部取れます。

その他の回答 (3)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>LVN_COLUMNCLICKもLVN系全てメッセージを捕まえれません。 >DialogBox関数で指定したプロシージャでなく更にサブクラス化しなければいけないのでしょうか?  そういう時は、Spy++で確認しましょう。

yruri
質問者

補足

Spy++試してみます。 なんかおもしろそうなソフトですけど、よく使われるものなんでしょうか?

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

>http://home.a03.itscom.net/tsuzu/programing/tips16.htm >を参考にして 参考にしたところが間違ってますね。 ドラッグリスト用のAPIです。 http://www.kumei.ne.jp/c_lang/sdk3/sdk_215.htm #"LB"なんですから。"LV"じゃないですよね? >その時のソースから流用したためNM_CLICKになっているのだと思います。 ということでしたら、この際LVN_COLUMNCLICKにしちゃいましょう。何も問題なくカラム情報を取得できます。

yruri
質問者

補足

LVN_COLUMNCLICKもLVN系全てメッセージを捕まえれません。 DialogBox関数で指定したプロシージャでなく更にサブクラス化しなければいけないのでしょうか?  ありがとうございます、試しに親プロシージャでWM_NOTIFYを引っ掛けてみます。

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

LVN_COLUMNCLICKではなく、なぜNM_CLICKを使用するのでしょうか? 特別な理由があるのでしたらしょうがないですけど。 あと、LBItemFromPtってリストボックスのAPIじゃなくて?

yruri
質問者

補足

http://home.a03.itscom.net/tsuzu/programing/tips16.htm を参考にして LBItemFromPt ListView_HitTest を試しましたがreturnは-1になってしまいます。 以前に一度自分で質問の内容と同じものを作ったことがあり、 その時のソースから流用したためNM_CLICKになっているのだと思います。 うろ覚えですがそのときにListViewからComboBoxの項目を選択状態にするという仕様と ComboBoxからListViewを選択状態にしたうえでさらにクリックするというのを作りました。 他にもいろいろ仕様がありそうしました。 結局動作が鈍くその部分のソースは書き捨ててしまいました。 ただ今回はDialogBoxマクロのプロシージャ内でやってるのが関係しているのかできないです。

関連するQ&A

  • xxx.iniファイルのデータ消去について

    よろしくお願いいたします。 アプリ終了時にWritePrivateProfileString(aaa,"X",szBuffer,"d:\\kado.ini");を使ってデータを書きこんでいます。 書きこむデータ数が一定ではないため、書きこむ前にデータを一旦消去したいのですが、そのような関数はあるのでしょうか? ご存知でしたらお教えください。 # 今は通常のファイルオープン if((fout=fopen("d:\\kado.ini","w"))==NULL) ・・・ で処理をしているのですが、WritePrivateProfileStringでの書きこみが出来るときと出来ないときが繰り返しで発生する不具合が生じています。

  • DirectXによる通信ができなくて困っています。

    DirectX9のDirectPlayで通信をしようとしているのですが、セッションへの接続が出来なくて困っています。 言語はC++で開発環境はVisualC++6.0です。プログラムは自分で組んだもので、ピアツーピア型。ホストとピア両方が出来るようにプログラムを組んで、同じプログラムを二つ起動して同一のマシンで実行しています。 接続が出来ない原因を調べたところ以下のセッションへの接続部分でプログラムが1~2分ほど固まり、その後接続に失敗していました。 hr = lpDirectPlay8Peer->Connect(&dpnAppDesc2, prgHostAddr,prgDeviceInfo2, NULL, NULL, NULL, 0, NULL, NULL, NULL,DPNCONNECT_OKTOQUERYFORADDRESSING | DPNCONNECT_SYNC); 接続に失敗した後、このエラー処理で接続に失敗した事は分かるのですが原因が分かりません。又、アドレスの設定やホストが確立しているかも同様の方法でエラーの判断をしています。 if (FAILED(hr)) //エラー処理 {MessageBox("セッションの接続に失敗", "PeerVoice", MB_OK | MB_ICONWARNING);} else {MessageBox("セッションの接続に成功", "PeerVoice", MB_OK | MB_ICONWARNING);} MSDNのIDirectPlay8Peer::Connectメソッドの項を見るとエラー時の戻り値でエラー原因が分かるようなので以下の様なコードを書きました。 switch (hr){ case S_OK: MessageBox("成功1", "PeerVoice", MB_OK |MB_ICONWARNING); break; case DPNSUCCESS_PENDING:("成功2", "PeerVoice", MB_OK |MB_ICONWARNING);break; case DPNERR_HOSTREJECTEDCONNECTION: MessageBox("失敗1", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDAPPLICATION : MessageBox("失敗2", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDDEVICEADDRESS : MessageBox("失敗3", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_INVALIDFLAGS: MessageBox("失敗4", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDHOSTADDRESS: MessageBox("失敗5", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINSTANCE: MessageBox("失敗6", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDINTERFACE: MessageBox("失敗7", "PeerVoice", MB_OK | MB_ICONWARNING);break; case DPNERR_INVALIDPASSWORD: MessageBox("失敗8", "PeerVoice", MB_OK | MB_ICONWARNING); break; case DPNERR_NOCONNECTION: MessageBox("失敗9","PeerVoice", MB_OK| MB_ICONWARNING);break; case DPNERR_NOTHOST: MessageBox("失敗10", "PeerVoice", MB_OK|MB_ICONWARNING);break; case DPNERR_SESSIONFULL: MessageBox("失敗11", "PeerVoice",MB_OK| MB_ICONWARNING);break; default: MessageBox("失敗0", "PeerVoice",B_OK|MB_ICONWARNING);break; } しかし、これでもdefaultの失敗0のメッセージボックスが出てきてしまいます。何かの設定ミスやホストがいないのなら上記のエラー処理で原因が特定できると思ったのですが、全くわけが分かりません。どうか理由が分かる方回答をお願いいたします。

  • 自作関数で元の値を変更したい

    ポインタとかが分からないので教えてください。 元のプロセスで  case WM_KEYDOWN:   MyFunc(hWnd);   if(!hWnd)MessageBox(NULL, "成功", "", MB_OK);   else MessageBox(NULL, "エラー", "", MB_OK);  break; 元のプロセスの自作関数で void MyFunc(HWND wnd){  SetWindowText(wnd, "てすと");//これはちゃんとできた。  wnd = NULL;//ここが失敗で、この関数を抜けるまでしか効果がない。 } これで MessageBox(NULL, "エラー", "", MB_OK); が実行されてしまいました。

  • ウインドウズフォルダにまつわる事

    VB2008でWindowsXP上でINIファイルの読み書きを行うプログラムを作っています。 VB.NETで特殊フォルダを取得したいのですが、以下の場合、 C:\Windows\System32となるのですが、C:\Windowsのようにウインドウズフォルダを返す方法はありますか? ' System ディレクトリ MessageBox.Show(System.Environment.GetFolderPath(System.Environment.SpecialFolder.System)) あとiniファイルをパスなしで作成するとC:\Windowsに作られるのですが デフォルトでそうなっているのでしょうか? WritePrivateProfileString("キーワード", "項目", 値, "test.ini") exeのあるカレントにiniファイルを作成したい場合などパスを求める方法等も知りたいです。

  • MessageBoxのことで聞きたいのですが…

    int i; int tmphyoukachi[KYOKU_SHUDAN]; bool cancel_flag; cancel_flag = false; ~~~~~~~~~ /*ユーザー評価(ダイアログでYES・NO)*/ int Rslt; Rslt = MessageBox(NULL, "", "",MB_YESNOCANCEL); if (Rslt == (IDYES)){ //Rslt = MessageBox(NULL, "YES","",MB_OK); kyoku[i][0] += 50000; } else if(Rslt == (IDNO)){ kyoku[i][0] -= 50000; }else if(Rslt == (IDCANCEL)){ cancel_flag = true; } mciSendString("close MIDIFILE",NULL,0,NULL); if(cancel_flag == true){ break; } } return cancel_flag; というような遺伝的アルゴリズムを用いて自動作曲システムを作りました。これはプログラムの一部なんですが、MessageBoxでカウントして何回目で終了というようなプログラムを作成したいのですが、どなたか分かるかたがいらっしゃいましたよろしくお願いします。

  • Vista 非同期接続

    Vista と VC++2005 でソケット関連のソフトを作っています。  下のようなコードでは BEGIN_MESSAGE_MAP(SQMailDLDlg, CDialog) // Don't show process //{{AFX_MSG_MAP(MailRecDlg2) ON_MESSAGE(SM_ASYNC, HandleAsyncMsg) //}}AFX_MSG_MAP END_MESSAGE_MAP() として、登録してある関数 HandleAsyncMsg() が呼び出されないのですが、 どこに原因があるのでしょうか? SendMessage(SM_ASYNC); とすれば、もちろん呼び出せます。 RetVal = getaddrinfo(gszServerName, Port, &Hints, &AddrInfo); if (RetVal != 0) { sprintf(outbuf3, "Cannot resolve address [%s] and port [%s], error %d: %s\n", Server, Port, RetVal, gai_strerror(RetVal)); WSACleanup(); return;// -1; } for (AI = AddrInfo; AI != NULL; AI = AI->ai_next) { ConnSocket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); if (ConnSocket == INVALID_SOCKET) { sprintf(outbuf3,"Error Opening socket, error %d: %s\n", WSAGetLastError(), DecodeError(WSAGetLastError())); continue; } if (WSAAsyncSelect(ConnSocket, *this, SM_ASYNC, FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT) == SOCKET_ERROR){ MessageBox("WSAAsyncSelect() failed","Error", MB_OK); closesocket(ConnSocket); ConnSocket = INVALID_SOCKET; continue; } if (connect(ConnSocket, AI->ai_addr, AI->ai_addrlen) == SOCKET_ERROR){ if(WSAGetLastError() != WSAEWOULDBLOCK){ closesocket(ConnSocket); ConnSocket = INVALID_SOCKET; continue; } break; } } if (AI == NULL) { sprintf(outbuf3, "Fatal error: unable to connect to the server.\n"); WSACleanup(); return;// -1; } よろしくお願いします。

  • fgetsで2行目から文字化け

    fgetsでファイルを一行ずつ読み込みたいのですが、二行目以降が文字化けしてしまいます。 ******* ソース ******* #include <windows.h> #include <stdio.h> FILE *fp; if ((fp = fopen("textlist.txt", "r")) == NULL){ MessageBox(NULL, TEXT("ファイルを開けません"), NULL, NULL); exit (1); } while (1) { TCHAR buf[128] = {0}; if (fgets(buf, sizeof(buf), fp) == NULL) break; MessageBox(NULL,buf,NULL,NULL); } fclose(fp); ***** textlist.txt ***** あいうえお かきくけこ さしすせそ メッセージボックスの一回目は正しく"あいうえお"と表示されますが、二回目・三回目は文字化けしています。 最終的に一行ずつ分けて配列に入れたいので、fgetsで出来たらと思っています。 よろしくお願いします。

  • winsockと、gmail。

    現在、 http://kumei.ne.jp/c_lang/sdk3/sdk_229.htm を参考にして、gmailに向けてメールを送信する プログラムを書いております。 が、メールを送信する前のconnectの部分で失敗してしまいます。 ソースは以下の通りです。 void main() { WSADATA wsaData; LPHOSTENT lpHost; LPSERVENT lpServ; SOCKET s; int iProtocolPort, iRtn; SOCKADDR_IN sockadd; const char*szServerName = "smtp.gmail.com"; if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) { MessageBox(NULL, "エラーです", "Error", MB_OK); return; } lpHost = gethostbyname(szServerName); if (lpHost == NULL) { MessageBox(NULL, "サーバが見つかりません", "Error", MB_OK); return; } s = socket(PF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) { MessageBox(NULL, "ソケットをオープンできません", "Error", MB_OK); return; } lpServ = getservbyname("mail", NULL); if (lpServ == NULL) { MessageBox(NULL, "ポート指定がされていないので、デフォルトを使います", "OK", MB_OK); iProtocolPort = htons(IPPORT_SMTP); } else { iProtocolPort = lpServ->s_port; } sockadd.sin_family = AF_INET; sockadd.sin_port = iProtocolPort; sockadd.sin_addr = *((LPIN_ADDR)*lpHost->h_addr_list); if (connect(s, (PSOCKADDR)&sockadd, sizeof(sockadd))) { /*ここでWSAGetLastError()をすると、WSAETIMEDOUTが返ってきます。*/ MessageBox(NULL, "サーバーソケットに接続失敗", "Error", MB_OK); return; } /*以下続く*/ } 上にあるように、connectの部分でタイムアウトになるようです。 当方、これらに関する周辺知識が足りておらず、 一体どこが間違えているのかすらわかりません。 どなたかこれが上手くいかない原因がわかる方、 是非、ご教授お願いします。

  • borland c++ によるMySQL へのアクセス

    borland c++でMySQLデータベースへ接続したいのですが、 外部シンボル 'mysql_real_connect' が未解決 外部シンボル 'mysql_init' が未解決 外部シンボル 'mysql_close' が未解決 というエラーが出てしまいます。 ******** 現状 *********** (1) インクルードしているヘッダファイルは、   <my_global.h>   <mysql.h>   <my_sys.h>   です。 (2) ソースコードは、  conn = mysql_init(NULL); if(mysql_real_connect(conn,opt_host_name,opt_user_name,opt_password,opt_db_name,opt_port_num,opt_socket_name,opt_flags) == NULL) { fprintf(stderr,"mysql_real_connect() failed\n"); mysql_close(conn); exit(1); } mysql_close(conn); exit(0); といった感じです。 (3) implib を用いて、   libmySQL.lib から libmySQL.dll へ変換し、   実行したいソースと同じフォルダに置き、   リンクしています。 どなたか、ご回答よろしくお願いいたします。                      

    • ベストアンサー
    • MySQL
  • midiの再生が思うようにできません

    ファイルの文字列を1行ずつ読み込み、文字列の数字の範囲によって再生する音楽を変えるプログラムを作成していますが、読み込んだ文字列とは無関係に、ループの初めの範囲で指定してある音楽しか再生されません。読み込んだ文字列ごとに再生音楽を変えるにはどうすればいいのでしょうか?分かる方ご教授願います。 環境:WindowsXP, Visual C++ 2008 Express Edition 以下がプログラムのソースの一部です。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { FILE *fp; errno_t err; TCHAR buf[30]; TCHAR *temp; int m=0, n=0; switch(msg) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), TEXT("Play"), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,120, 100, 70, 70, hWnd, NULL, hInst, NULL); break; case WM_COMMAND: err = _tfopen_s(&fp, TEXT("C:\\Documents and Settings\\m22015\\My Documents\\Visual Studio 2008\\Projects\\process\\process\\Corner.txt"), TEXT("r+")); if(err != 0) break; temp = (TCHAR*)malloc(_tcsclen(buf)+1); if(temp == NULL){ MessageBox(hWnd, TEXT("Can't secure of memory"), TEXT("Error"), MB_OK); break; } for(int i=0; i<2; i++){ _fgetts(buf, 10, fp); _tcstok(buf, TEXT("\n")); } while(_fgetts(buf, 30, fp) != NULL){ _tcstok(buf, TEXT("\n")); _tcscpy(temp, buf); while(_stprintf(buf, _T("- { x:%d, y:%d }"), m, n)!=EOF){ if((m>=0 && m<110)&&(n>=0 && n<200)){ if(mciSendString(_T("play C+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=0 && n<200)){ if(mciSendString(_T("play D+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=220 && m<330)&&(n>=0 && n<200)){ if(mciSendString(_T("play E+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play E+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=330 && m<440)&&(n>=0 && n<200)){ if(mciSendString(_T("play F+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play F+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=440 && m<550)&&(n>=0 && n<200)){ if(mciSendString(_T("play G+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play G+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=550 && m<660)&&(n>=0 && n<200)){ if(mciSendString(_T("play A+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play A+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=660 && m<770)&&(n>=0 && n<200)){ if(mciSendString(_T("play B+1.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play B+1.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if(mciSendString(_T("play C.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play C.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; }else if((m>=110 && m<220)&&(n>=200 && n<400)){ if(mciSendString(_T("play D.mid"), NULL, 0, NULL) != 0) { MessageBox(hWnd, _T("Can't play D.mid"), _T("Error"), MB_OK); SendMessage(hWnd, WM_CLOSE, 0, 0); } return 0; 以下省略 . . . }else{ break; } } } free(temp); fclose(fp); break; case WM_CLOSE: DestroyWindow(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wParam, lParam)); } return 0; }

専門家に質問してみよう