WindowsAPIのリストビューのチェックボックスでの質問

このQ&Aのポイント
  • 開発環境はVS.NET2003で、リストビューでチェックボックスを使っているが、チェックボックスを1つしかチェックできないようにしたい。
  • 拡張スタイルであるLVS_EX_CHECKBOXESを指定してチェックボックスのあるリストビューを作成したが、チェックできるのが一つのみにしたい。
  • LV_DISPINFO構造体を使ってメッセージを受け取るが、変更を行うべきかどうかわからない。ListCheckBoxクラスは使用しない方法を知りたい。
回答を見る
  • ベストアンサー

 WindowsAPIのリストビューのチェックボックスでの質問

 WindowsAPIのリストビューのチェックボックスでの質問 開発環境はVS.NET2003です。 リストビューでチェックボックスを使っているのですが、 チェックボックスを1つしかチェックできないようにしたいのです。 リストビューの拡張スタイルであるLVS_EX_CHECKBOXESを指定してチェックボックスのあるリストビューを作成したのですが、チェックできるのが一つのみにしたいのです。 LVN、LVNIメッセージを調べたのですが、これに該当するものが見つからないためここで質問しました。 LV_DISPINFO構造体を使ってメッセージを受け取るのですが、ここで変更を行ったほうがいいんでしょうか? C++とありましたが、ListCheckBoxクラスを使用していません。 このクラスを使用しない方法をお願いします。  

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

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

 こんばんは。  WM_NOTIRYメッセージ内のLVN_ITEMCHANGEDで、以前クリックされたリスト項目に向かって、チェックを外す処理をするしかなさそうです。  http://msdn.microsoft.com/en-us/library/bb774845(VS.85).aspx  flag = (pnmv->uNewState & LVIS_STATEIMAGEMASK)として、  flag == INDEXTOSTATEIMAGEMASK(1)が、チェック無し、  flag == INDEXTOSTATEIMAGEMASK(2)が、チェックありです。  同じチェックボックスをクリックされて、チェックが外れてしまった時の事は考えていませんが、大体以下の様な感じです。参考程度で。 case WM_NOTIFY: { static int _S_iOldItem = -1; LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; if(pnmv->hdr.idFrom == IDC_LISTVIEW1) { switch(pnmv->hdr.code) { case LVN_ITEMCHANGED: { const int iState = pnmv->uNewState & LVIS_STATEIMAGEMASK; //チェックされた if(iState == INDEXTOSTATEIMAGEMASK(2)) { //以前クリックされたアイテムからチェックを外す if(_S_iOldItem != -1) { LVITEM item = {sizeof(item)}; item.mask = LVIF_STATE; item.stateMask = -1; item.iItem = _S_iOldItem; ListView_GetItem(pnmv->hdr.hwndFrom, &item); item.state &= ~LVIS_STATEIMAGEMASK; item.state |= INDEXTOSTATEIMAGEMASK(1); ListView_SetItem(pnmv->hdr.hwndFrom, &item); } _S_iOldItem = pnmv->iItem; } } break; } } } break;

dotneer
質問者

お礼

回答ありがとうございます。 お陰でチェックボックスのチェックを外すことができました。 uNewStateメンバにマスクをして、チェックされているかをINDEXTOSTATEIMAGEMASK(2)で 判定すればいいんですね。 ListView_SetCheckStateマクロを使ってもうまくいくみたいです。 ソースを載せてくださり本当に感謝しています。 ありがとうございます。m( )m

関連するQ&A

  • VB6 API LISTVIEW(チェックボックス付き)にチェックを付けたい

    CreateWindowExでLISTVIEW(チェックボックス付きのレポートビュー)を作ったのですが、「山田花子」行にソースでチェックを付ける方法が分かりません。 Form1のソース ↓ Option Explicit Private Sub Form_Load() Dim lngRet As Long Dim lvcol As LV_COLUMN Dim rStyle As Long Dim item As LV_ITEM '-- リストビューの作成 hList = CreateWindowEx(WS_EX_CLIENTEDGE, _ WC_LISTVIEW, "", _ WS_CHILD Or WS_VISIBLE Or WS_BORDER Or _ WS_CLIPSIBLINGS Or WS_CLIPCHILDREN Or _ LVS_REPORT, _ 0&, 0&, Me.ScaleWidth / Screen.TwipsPerPixelX, 200&, _ Me.hwnd, _ 0&, _ App.HINSTANCE, _ ByVal 0&) '拡張スタイルを設定 rStyle = rStyle Or LVS_EX_FULLROWSELECT Or LVS_EX_GRIDLINES Or LVS_EX_CHECKBOXES SendMessageByNum hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0&, rStyle '-- カラムヘッダーの追加 With lvcol .mask = LVCF_FMT Or LVCF_WIDTH Or LVCF_TEXT Or LVCF_SUBITEM .fmt = LVCFMT_LEFT .cx = 100 .pszText = "名前" .iSubItem = 0 lngRet = ListView_InsertColumn(hList, 0&, lvcol) End With '-- リストアイテムの追加 With item .mask = LVIF_TEXT Or LVIF_IMAGE ' 1つめ .pszText = "山田 太郎" .iItem = 0 .iSubItem = 0 .iImage = 0 lngRet = ListView_InsertItem(hList, item) ' 2つめ .pszText = "山田 花子" .iItem = 1 .iSubItem = 0 .iImage = 1 lngRet = ListView_InsertItem(hList, item) End With End Sub Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer) '-- リストビューを破棄 DestroyWindow hList End Sub 標準モジュールは補足に書きます

  • リストビューで選択行の背景を変える

    お世話になります。リストビューの選択行の背景色を変えたいと思い、カスタムドローを用い以下のようにしましたが、選択していない所も赤になってしまいます。 if (lplvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) {  // 選択行の背景色を変更  if (lplvcd->nmcd.uItemState & CDIS_SELECTED) {   lplvcd->clrTextBk = RGB(255, 0, 0);   lplvcd->nmcd.uItemState &= ~CDIS_SELECTED;  } else {   lplvcd->clrTextBk = RGB(255, 255, 255);  }  return CDRF_NOTIFYSUBITEMDRAW; } デバッグモードで見ると、else以降の分は解釈されていないようです。 リストビューは g_hList = CreateWindowEx(0 , WC_LISTVIEW , 0 , WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_NOSORTHEADER | LVS_SHOWSELALWAYS, 1 , 1 , width , lv_height , g_hMain , (HMENU)1 , g_hInst , NULL); dwStyle = ListView_GetExtendedListViewStyle(g_hList); dwStyle |= LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES; ListView_SetExtendedListViewStyle(g_hList, dwStyle); ListView_SetBkColor(g_hList, RGB(240,240,240)); のようにしています。宜しくお願いします

  • リストビューのスクロールについて

    VC.NET MFC でリストビュー(CListCtrl)を使用しています。 そのリストビューにある垂直スクロールバーを操作しても、 PreTranslateMessage()になにもコマンドが送られてきません。 ・・・(1) また、LVN_BEGINSCROLLのハンドラを追加してみたんですが、 コンパイル時にLVN_BEGINSCROLLを認識してもらえません。 (コンパイルエラー) ・・・(2) いろいろ調べてcommctrl.hをインクルードしても 必要なDLL(Comctl32.lib ? Comclt32.lib)をプロジェクトに参加させても認識してもらえませんでした。 リストビューのスクロールバー操作時の処理をオーバーロードしたいのですが、できなくて困っています。 どのようにすればよろしいでしょうか? 助言のほどよろしくお願いします。

  • リストビューのコンボボックス

    こんにちは。 リストビューについて質問させて頂きます。 リストビューの中3列があって、2番目の列にコンボボックスに表示したいけど、どうやって以下のリンクのソースを修正すればいいか教えてくれますか。ありがとうございます。 http://support.microsoft.com/kb/320342/jp​

  • CListCtrlのcheckboxサイズ変更

    WindowsCE、MFC、C++で実装しています。 CListCtrlで表を作成し、 下記の方法でチェックボックスを表示させました。 CListCtrl m_list; m_list.SetExtendedStyle((m_lstCheck.GetExtendedStyle()|LVS_EX_CHECKBOXES)); チェックボックス(画像参照)のサイズを大きくしたいのですが、 方法がわかりません。 (SetFont()関数で試してみましたが、文字にしか反映されませんでした。)

  • リストビューの項目の内容を変更する方法は?

    お世話になります。 VS2005を使用しています。 VB.NETのリストビューで一覧を作ったのですが、その中の項目の内容をプログラム内から変更することは出来ないのでしょうか? 色々検索してみたのですが見つかりませんでした。 現在、リストビューには4つの項目があり、100行くらい有ります。 (1つ目の項目にはチェックボックス付き) その中の、項目の内容を変更したいのです。 やはり、以下のようにしなければいけないのでしょうか。 1)一旦対象行の内容を保存 2)対象行を削除 3)保存先で内容変更 4)リストビューに再追加 よろしくご享受下さい。

  • お願いします! リストボックスの扱い方

    切羽詰まってます。なにとぞお願いします。m(__)m ALLと付けた あるチェックボックスをチェックすると、 その下にある配置した リストボックスが選択できなく なるか ( disabled ) もしくは、リストボックスの 1行目をのぞいて(選択してください、メッセージがある) 全部選択された状態になる、スクリプトはどう書けば いいんでしょう。 本を何冊か買っていろいろみているんですが、具体例が 載ってなくほとほと弱っています。

  • リストビューのカスタムドローについて

    Windows XP SP3 + Visual Studio 2008 C++ で、リストビューを使用したダイアログベースのソフトを作っています。 リストビューには、ファイル名、ファイルサイズ、最終更新日時を「詳細」で表示させています。(よくあるファイル一覧です。) エクスプローラと同じように、ファイル名等のテキストを NTFS の圧縮ファイルは青 暗号化ファイルは緑 で表示させようと思い、カスタムドローを使用しています。 また、圧縮でもなく暗号化でもないファイルに対しては、ChooseFont() で選択された色 ( CHOOSEFONT 構造体の rgbColors ) を設定しています。 ChooseFont() で選択した色のうち、濃紺以外の色は問題なく表示されているのですが、なぜか、ChooseFont で濃紺 ( 0x00800000 ) を選択した場合だけ、第一列 ( ファイル名 ) のみ濃紺になり、第二列目以降 ( ファイルサイズ、最終更新日時 ) が、システム設定値 ( 黒 ) となります。 しかも、リストビューのスタイルを拡張スタイルの LVS_EX_FULLROWSELECT ( 行選択モード? ) にすると、濃紺の場合でも、第二列目以降も正常に表示されます。 コーディングは、カスタムドローの部分だけを抜粋すると以下のような感じになっています。 LPNMLVCUSTOMDRAW pnmlvcd; LVITEM lvi; DWORD dwAttributes; switch( message ) { case NM_CUSTOMDRAW:   pnmlvcd = ( LPNMLVCUSTOMDRAW )lParam;   switch( pnmlvcd->nmcd.dwDrawStage ) {   case CDDS_PREPAINT:     SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_NOTIFYITEMDRAW );     return( TRUE );   case CDDS_ITEMPREPAINT:     lvi.mask = LVIF_PARAM;     lvi.iSubItem = 0;     lvi.iItem = pnmlvcd->nmcd.dwItemSpec; // 描画しようとしている行のインデックス     if( ListView_GetItem( hwndList, &lvi ) ) {       // 属性を取得       // lvi.lParam はファイルの情報を格納した構造体 FILEITEM へのポインタです。       dwAttributes = ( ( PFILEITEM )lvi.lParam )->dwAttributes;       if( 通常ファイルの場合 ) {  // dwAttributes を使用して属性を判定         // ChooseFont で選択した色を設定         pnmlvcd->clrText = cfList.rgbColors;         SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );         return( TRUE );       } else if( 圧縮ファイルの場合 ) {  // dwAttributes を使用して属性を判定         // 青         pnmlvcd->clrText = RGB( 0, 0, 0xff );         SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );         return( TRUE );       } else if( 暗号化ファイルの場合 ) {  // dwAttributes を使用して属性を判定         // 緑         pnmlvcd->clrText = RGB( 0, 0xff, 0 );         SetWindowLong( hwndMain, DWL_MSGRESULT, ( LONG )CDRF_DODEFAULT );         return( TRUE );       }     }   }   break; hwndMain はダイアログのウィンドウハンドル、hwndList はリストビューのウィンドウハンドルです。 (見やすくするため、スペースに全角スペースを使用しています。また、属性の判定部分は実際には dwAttributes との、&、| を使用しています。) コーディング的には、ChooseFont() で何色が選択されようが知ったこっちゃないという感じなのですが・・・。 試しに、ChooseFont() で選択した色ではなく、RGB( 0, 0, 0x80 ) を指定しても同様の現象でした。 濃紺の場合でも、LVS_EX_FULLROWSELECT でなくても第二列目以降が正しい色で表示されるようにする方法はないでしょうか。 このリストビューは Drag & Drop のソース側の機能も実装していまして、その影響で、LVS_EX_FULLROWSELECT だと、Drag 操作による複数行選択の操作が難しくなるので、LVS_EX_FULLROWSELECT は避けたいと考えています。 あるいは、上記のコーディングで、何かおかしいんじゃないかという部分がありましたら教えていただけませんでしょうか。 よろしくお願いします。

  • チェックボックスの値を取得したい。

    アンケートシートにコントロールツールボックスからチェックボックスを60個作りました。 その値を取得するため、次の構文を作りましたが、 実行時エラー1004 「WorksheetクラスのCheckBoxesプロパティを取得できません。」というMsgboxが出ます。 何方か良い知恵をお貸し下さい。 <エラーのでる構文> Sub AAA() Dim A Sheets(1).Select For A = 1 To 60 Cells(A, 5) = Sheets(1).CheckBoxes(A).Value Next A End Sub Excelは2003です。

  • EXCELでチェックボックスの一括オンオフ

    EXCEL2000を使用してます。 アンケート作成をしており、設問毎にチェックボックスで複数選択できるようにしていますが、1つの設問にチェックボックスが8~10等多くあるため、設問毎にチェックボックスの一括オンオフができるようにしたいのです。 今は、次の記述で、ある設問のみ全てのチェックボックスにレが入りますが、はずす事ができません。 Sub チェック11_Click() ActiveSheet.CheckBoxes(Array(1, 2, 3)).Value = True End Sub どうすれば、チェック11のボックスで、オンオフができるのでしょうか? どうか教えて頂きますよう、よろしくお願い致します。

専門家に質問してみよう