Du kan starte med:
#include <windows.h>
#ifndef _WIN32_IE
#define _WIN32_IE 0x0300
#endif
#include <commctrl.h>
#include <stdio.h>
#include <string>
#include <vector>
#define IDC_TREE 1200
#define IDM_INIT_MESSAGE 10000
HINSTANCE InstanceHandle;
std::vector<std::string >DirList;
void Dir2Tree(HWND aWndTree, HTREEITEM aParent, const char* aStart, int aLevel)
{
TVINSERTSTRUCT TVInsertStruct;
memset(&TVInsertStruct, 0, sizeof(TVInsertStruct));
TVInsertStruct.hParent = aParent;
TVInsertStruct.hInsertAfter = TVI_LAST;
TVInsertStruct.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
WIN32_FIND_DATA FindData;
HANDLE FindHandle = FindFirstFile((std::string(aStart) + "\\\\*").c_str(), &FindData);
if(FindHandle != INVALID_HANDLE_VALUE)
{
do
{
if((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
strcmp(FindData.cFileName, ".") &&
strcmp(FindData.cFileName, ".."))
{
TVInsertStruct.item.pszText = FindData.cFileName;
std::string Temp = std::string(aStart) + "\\\\" + FindData.cFileName;
TVInsertStruct.item.lParam = (LPARAM )strdup(Temp.c_str());
SHFILEINFO ShFileInfo;
if(!SHGetFileInfo(Temp.c_str(), 0, &ShFileInfo, sizeof(ShFileInfo), SHGFI_SYSICONINDEX | SHGFI_SMALLICON))
{
MessageBox(0, Temp.c_str(), "No icon...", 0);
}
TVInsertStruct.item.iImage = ShFileInfo.iIcon;
TVInsertStruct.item.iSelectedImage = ShFileInfo.iIcon;
HTREEITEM Item = (HTREEITEM )SendMessage(aWndTree, TVM_INSERTITEM, 0, (LPARAM )&TVInsertStruct);
if(aLevel == 0)
{
Dir2Tree(aWndTree, Item, Temp.c_str(), aLevel + 1);
}
}
}
while(FindNextFile(FindHandle, &FindData));
FindClose(FindHandle);
}
}
void Disk2Tree(HWND aWndTree)
{
TVINSERTSTRUCT TVInsertStruct;
memset(&TVInsertStruct, 0, sizeof(TVInsertStruct));
TVInsertStruct.hInsertAfter = TVI_ROOT;
TVInsertStruct.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
DWORD Drives = GetLogicalDrives();
int i;
for(i = 0; i < 32; i++)
{
if(Drives & (1 << i))
{
char Temp[32] = "A:\\\\";
Temp[0] = char('A' + i);
TVInsertStruct.item.pszText = Temp;
TVInsertStruct.item.lParam = (LPARAM )strdup(Temp);
SHFILEINFO ShFileInfo;
HIMAGELIST ImageList = (HIMAGELIST )SHGetFileInfo(Temp, 0, &ShFileInfo, sizeof(ShFileInfo), SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
TVInsertStruct.item.iImage = ShFileInfo.iIcon;
TVInsertStruct.item.iSelectedImage = ShFileInfo.iIcon;
if(ImageList)
{
SendMessage(aWndTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM )ImageList);
}
TVInsertStruct.item.lParam = (LPARAM )strdup(Temp);
memset(&ShFileInfo, 0, sizeof(ShFileInfo));
if(SHGetFileInfo(Temp, 0, &ShFileInfo, sizeof(ShFileInfo), SHGFI_DISPLAYNAME))
{
TVInsertStruct.item.pszText = ShFileInfo.szDisplayName;
}
else
{
TVInsertStruct.item.pszText = Temp;
}
HTREEITEM Item = (HTREEITEM )SendMessage(aWndTree, TVM_INSERTITEM, 0, (LPARAM )&TVInsertStruct);
Temp[2] = 0;
Dir2Tree(aWndTree, Item, Temp, 0);
}
}
}
void DeleteItem(HWND aTreeWnd, HTREEITEM aItem)
{
TVITEM Item;
Item.mask = TVIF_PARAM | TVIF_HANDLE | TVIF_STATE;
Item.hItem = aItem;
Item.stateMask = TVIS_STATEIMAGEMASK;
if(SendMessage(aTreeWnd, TVM_GETITEM, 0, (LPARAM )&Item))
{
char *txt = (char *)Item.lParam;
if(!(Item.state & (1 << 12)))
{
DirList.push_back(txt);
}
SendMessage(aTreeWnd, TVM_DELETEITEM, 0, (LPARAM )aItem);
free(txt);
}
}
void RemoveChild(HWND aTreeWnd, HTREEITEM aRoot)
{
// First all childs
HTREEITEM Child = (HTREEITEM )SendMessage(aTreeWnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM )aRoot);
while(Child)
{
RemoveChild(aTreeWnd, Child);
HTREEITEM Next = (HTREEITEM )SendMessage(aTreeWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM )Child);
DeleteItem(aTreeWnd, Child);
Child = Next;
}
// Then all my siblings
do
{
HTREEITEM Next = (HTREEITEM )SendMessage(aTreeWnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM )aRoot);
DeleteItem(aTreeWnd, aRoot);
if(Next)
RemoveChild(aTreeWnd, Next);
aRoot = Next;
}
while(aRoot);
}
LRESULT CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
{
CreateWindowEx(WS_EX_CLIENTEDGE,
WC_TREEVIEW,
"",
WS_CHILD | WS_VISIBLE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_CHECKBOXES,
5, 5, 100, 20,
hwndDlg,
(HMENU)(IDC_TREE),
InstanceHandle,
0);
PostMessage(hwndDlg, IDM_INIT_MESSAGE, 0, 0);
}
break;
case IDM_INIT_MESSAGE:
Disk2Tree(GetDlgItem(hwndDlg, IDC_TREE));
break;
case WM_NOTIFY:
{
NMHDR* Header = (NMHDR *)lParam;
if(Header->code == TVN_ITEMEXPANDING)
{
NMTREEVIEW* NMTreeView = (NMTREEVIEW*)lParam;
TVITEM Item;
Item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_HANDLE;
Item.hItem = NMTreeView->itemNew.hItem;
char Temp[1024];
Item.pszText = Temp;
Item.cchTextMax = sizeof(Temp);
SendMessage(Header->hwndFrom, TVM_GETITEM, 0, (LPARAM )&Item);
HTREEITEM Child = (HTREEITEM )SendMessage(Header->hwndFrom, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM )NMTreeView->itemNew.hItem);
if(Child)
{
TVITEM ChildItem;
ChildItem.mask = TVIF_PARAM | TVIF_TEXT | TVIF_HANDLE | TVIF_CHILDREN;
char Temp2[1024];
ChildItem.pszText = Temp2;
ChildItem.cchTextMax = sizeof(Temp2);
do
{
ChildItem.hItem = Child;
SendMessage(Header->hwndFrom, TVM_GETITEM, 0, (LPARAM )&ChildItem);
if(ChildItem.cChildren == 0)
{
Dir2Tree(Header->hwndFrom, Child, (char *)ChildItem.lParam, 1);
}
// MessageBox(hwndDlg, ChildItem.pszText, (char *)ChildItem.lParam, 0);
Child = (HTREEITEM )SendMessage(Header->hwndFrom, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM )Child);
}
while(Child);
}
}
}
break;
case WM_CLOSE:
{
HWND TreeWnd = GetDlgItem(hwndDlg, IDC_TREE);
HTREEITEM Root = (HTREEITEM )SendMessage(TreeWnd, TVM_GETNEXTITEM, TVGN_ROOT, 0);
RemoveChild(TreeWnd, Root);
}
break;
case WM_SIZE:
RECT R;
GetClientRect(hwndDlg, &R);
MoveWindow(GetDlgItem(hwndDlg, IDC_TREE), 5, 5, R.right - 10, R.bottom - 10, TRUE);
break;
case WM_COMMAND:
break;
}
return DefWindowProc(hwndDlg, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, INT)
{
InstanceHandle = hInstance;
InitCommonControls();
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = DialogProc;
wc.hInstance = InstanceHandle;
wc.hbrBackground = (HBRUSH )(COLOR_BTNFACE + 1);
wc.lpszClassName = "WhateverClass";
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClass(&wc))
return FALSE;
HWND WindowHandle = CreateWindow("WhateverClass",
"Whatever", // Caption text
WS_MINIMIZEBOX | WS_VISIBLE | WS_CLIPSIBLINGS | WS_THICKFRAME |
WS_CLIPCHILDREN | WS_MAXIMIZEBOX | WS_CAPTION | WS_BORDER | WS_SYSMENU,
100, 100, 500, 500, // Position
NULL,
NULL,
InstanceHandle,
0);
MSG Msg;
while(GetMessage(&Msg, WindowHandle, 0, 0xFFFF) > 0)
{
if(!IsDialogMessage(WindowHandle, &Msg))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
return 0;
}
Det viser filer på alle disks som et træ. Det læser en frygtelig masse når det starter op, så der varer lidt længe inden det viser noget.