
No.1ベストアンサー
- 回答日時:
こんにちは。
「+/-」ボタンの変更は出来ないようですので、カスタムドローを使って描くしか道は無いのかもしれません。
http://lhsp.s206.xrea.com/misc/customdraw.html
http://www.kumei.ne.jp/c_lang/sdk3/sdk_262.htm
ダイアログの戻り値はTRUE/FALSEなので、カスタムドローメッセージの戻り値の為に、
SetWindowLong(hDlg, DWL_MSGRESULT, lResult)
を必ず呼び出します。
取り合えず以下は「+/-」ボタンに見立てて「!アイコン」と「?アイコン」をイメージリストにしてから、子持ちのツリーアイテムの横に描かせています。
阿弥陀籤の様な線は自前で描こうとすると地獄そのものなので、割愛しています。参考程度に。
#include<windows.h>
#include<commctrl.h>
#include<tchar.h>
#include"resource.h"
#pragma comment(lib, "comctl32.lib")
#define ArrayCount(a) (sizeof(a)/sizeof(a[0]))
const LPCTSTR TSTR_IMGLIST = TEXT("image list");
typedef struct tagMessage
{
union
{
HWND hWnd;
HWND hDlg;
HWND hCtl;
};
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
} Message;
static void TreeView_SetLParam(HWND hTV, HTREEITEM hTreeItem)
{
TVITEM item = {TVIF_PARAM};
item.lParam = (LPARAM)hTreeItem;
item.hItem = hTreeItem;
TreeView_SetItem(hTV, &item);
}
static HTREEITEM TreeView_Add(HWND hTV, HTREEITEM hTreeParent, LPCTSTR pszItem)
{
TVINSERTSTRUCT tvi = {0};
tvi.hParent = hTreeParent;
tvi.item.mask = TVIF_TEXT;
tvi.item.pszText = (LPTSTR)pszItem;
HTREEITEM hTreeItem = TreeView_InsertItem(hTV , &tvi);
::TreeView_SetLParam(hTV, hTreeItem);
return hTreeItem;
}
static void OnTVCustomDraw(Message& m, const LPNMTVCUSTOMDRAW p)
{
TCHAR sItem[256] = {0};
HIMAGELIST hImgList = (HIMAGELIST)::GetProp(m.hDlg, TSTR_IMGLIST);
HTREEITEM hTreeItem = (HTREEITEM)p->nmcd.lItemlParam;
//ツリーアイテムからアイテム情報を取り出す
TVITEM item = {TVIF_TEXT | TVIF_CHILDREN | TVIF_STATE};
item.hItem = hTreeItem;
item.pszText = sItem;
item.cchTextMax = ArrayCount(sItem);
TreeView_GetItem(p->nmcd.hdr.hwndFrom, &item);
const DWORD dwDTStyle = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
//ツリーアイテム欄の高さ
const LONG lHeight = p->nmcd.rc.bottom - p->nmcd.rc.top;
RECT rcText = {(p->iLevel + 1) * lHeight, p->nmcd.rc.top, p->nmcd.rc.right, p->nmcd.rc.bottom};
//正確なテキスト領域を取る
::DrawText(p->nmcd.hdc, sItem, ::_tcslen(sItem), &rcText, dwDTStyle | DT_CALCRECT);
//テキスト領域を塗り潰す(クリックする度にフォーカスの残骸が残る為)
::FillRect(p->nmcd.hdc, &rcText, (HBRUSH)::GetStockObject(WHITE_BRUSH));
//テキストを書き込む
::DrawText(p->nmcd.hdc, sItem, ::_tcslen(sItem), &rcText, dwDTStyle);
//ツリーアイテムが子持ち
if(item.cChildren == 1)
{
//イメージリストの使用位置を決める
const INT nIndex = (item.state & TVIS_EXPANDED) ? 0 : 1;
::ImageList_Draw(hImgList, nIndex, p->nmcd.hdc, p->iLevel * lHeight, p->nmcd.rc.top, ILD_NORMAL);
}
//フォーカスを描く
if(p->nmcd.uItemState == (CDIS_FOCUS | CDIS_SELECTED))
::DrawFocusRect(p->nmcd.hdc, &rcText);
}
static LRESULT OnInitDialog(Message& m)
{
//イメージリストの準備
HIMAGELIST hImgList = ::ImageList_Create(14, 14, ILC_COLOR32 | ILC_MASK, 2, 1);
::ImageList_AddIcon(hImgList, ::LoadIcon(NULL, IDI_QUESTION));
::ImageList_AddIcon(hImgList, ::LoadIcon(NULL, IDI_ASTERISK));
::SetProp(m.hDlg, TSTR_IMGLIST, hImgList);
//適当にツリーを作る
HWND hTV = ::GetDlgItem(m.hDlg, IDC_TREE1);
HTREEITEM hTreeNest = NULL;
HTREEITEM hTreeItem = ::TreeView_Add(hTV, TVI_ROOT, TEXT("parent1"));
::TreeView_Add(hTV, hTreeItem, TEXT("item1"));
hTreeNest = ::TreeView_Add(hTV, hTreeItem, TEXT("item1"));
::TreeView_Add(hTV, hTreeNest, TEXT("item2"));
::TreeView_Add(hTV, hTreeItem, TEXT("item3"));
::TreeView_Add(hTV, TVI_ROOT, TEXT("parent2"));
hTreeNest = ::TreeView_Add(hTV, TVI_ROOT, TEXT("parent3"));
::TreeView_Add(hTV, hTreeNest, TEXT("item1"));
return 0;
}
static LRESULT OnNotify(Message& m)
{
LPNMTVCUSTOMDRAW p = (LPNMTVCUSTOMDRAW)m.lParam;
if(p->nmcd.hdr.idFrom != IDC_TREE1)
return FALSE;
if(p->nmcd.hdr.code != NM_CUSTOMDRAW)
return FALSE;
switch (p->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
::SetWindowLong(m.hDlg, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW);
return TRUE;
case CDDS_ITEMPREPAINT:
::OnTVCustomDraw(m, p);
::SetWindowLong(m.hDlg, DWL_MSGRESULT, CDRF_SKIPDEFAULT);
return TRUE;
}
return 0;
}
static LRESULT OnClose(Message& m)
{
HIMAGELIST hImgList = (HIMAGELIST)::GetProp(m.hDlg, TSTR_IMGLIST);
::ImageList_Destroy(hImgList);
::RemoveProp(m.hDlg, TSTR_IMGLIST);
::DestroyWindow(m.hDlg);
return 0;
}
int CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Message m = {hDlg, uMsg, wParam, lParam};
switch(uMsg)
{
case WM_INITDIALOG:
::OnInitDialog(m);
break;
case WM_NOTIFY:
::OnNotify(m);
break;
case WM_CLOSE:
::OnClose(m);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return FALSE;
}
return TRUE;
}
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
::InitCommonControls();
HWND hWnd = ::CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_DIALOG1), NULL, &::DlgProc, 0);
::ShowWindow(hWnd, nCmdShow);
while(::GetMessage(&msg, NULL, 0, 0) == TRUE)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return msg.wParam;
}
こんにちは。
カスタムドローについては自分も同じ結論に至りましたが、ではどうしたものかと悩んでいました。
非常に詳しいサンプルをありがとうございます。
未熟なためちょっとまだうまく動いてはくれませんが、いろいろ試したいと思います。
ありがとうこざいました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 画像編集・動画編集・音楽編集 gomcamの起動にブロックがかかる 1 2023/07/28 23:34
- PDF PDFファイルのアイコン 2 2022/04/15 20:48
- Windows 10 windows11 update の「更新の再開」について初歩的な質問なのですが 1 2022/10/19 00:57
- フリーソフト AutoHotKeyは別の独立したファイルで 動作させる方法はないのでしょうか 1 2022/09/04 13:14
- C言語・C++・C# C#の2つの実行ファイルとアプリアイコンの変更について 1 2023/01/07 16:57
- ヤフオク! ヤフオクに出品したいのですが、タグを実行出来ません。 2 2022/09/16 12:36
- Windows 10 エクスプローラーが開かなくなった? 1 2022/07/07 15:34
- その他(OS) Windows11でアイコンが変更できない 1 2022/12/15 16:38
- Windows 10 エクスプローラでリスト表示かつその場で階層表示はできますか? 1 2022/09/02 01:48
- Windows 10 Windowsのアイコンの整列が変になりました 2 2022/06/24 00:02
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
不明なエラー
-
COMPORTマルチスレッドで例外発生
-
エラー Run-Time Check Failur...
-
エディットボックスの背景の色...
-
C言語win32api、エディットボッ...
-
cocoa objective-c の return ...
-
Aの値からBの値を除するとは??
-
fgetsなどのときのstdinのバッ...
-
「指定されたキャストは有効で...
-
Enterキーを押されたら次の処理...
-
java初心者です。入力されたの...
-
C言語のステップ数をカウントす...
-
10個出力で改行したいのですが...
-
数字以外が入力されたらエラー...
-
C言語での引数の省略方法
-
2÷3などの余りについて
-
ExcelでPC(パソコン)によって...
-
プログラムでの数字につく”f”の...
-
エクセルで可視セルにのみ値貼...
-
DWORDの実際の型は何でしょうか
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エディットボックスの背景の色...
-
ダイアログプログラムでEnterキ...
-
エラー Run-Time Check Failur...
-
プログラミングでエラーが出ま...
-
ボタンの色(WINAPI)
-
Win32APIでウィンドウを中央に...
-
C言語win32api、エディットボッ...
-
C#のswitch文を簡略化したいの...
-
ウィンドウ非表示に時に表示し...
-
不明なエラー
-
COMPORTマルチスレッドで例外発生
-
WM_CREATE について
-
コンソールアプリケーションの...
-
別関数に渡す変数のポインタが...
-
作成プログラムを常にアクティ...
-
DialogBox
-
【Windowsアプリ】ファイルのド...
-
オーバーレイみたいな処理がしたい
-
ボタンのアイコン表示
-
ウィンドウのサイズ変更について
おすすめ情報