#include "stdafx.h"
#include <commctrl.h>
#include "UI.h"
#include "SDK_Utility.h"
#define MAX_LOADSTRING 100
#define READ_FROM_BUTTON 1000
#define READ_FROM_EDITBOX 1001
#define FBX_TREEVIEW 1002
HINSTANCE hInst;
HWND ghWnd = NULL;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
char gszInputFile[MAX_PATH];
extern KFbxSdkManager *gSdkManager;
extern KFbxScene *gScene;
ATOM UIRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void CreateUIControls(HWND hWndParent);
void GetInputFileName(HWND hWndParent);
HTREEITEM InsertTreeViewItem(const HWND hTv, const char *txt, HTREEITEM htiParent);
void Expand_All();
void Expand_All_Recurse(HWND htv, HTREEITEM htvi);
void DisplayHierarchy(const HWND hTv);
void DisplayHierarchy_Recurse(const KFbxNode* pNode, HWND hTv, HTREEITEM htiParent);
void Add_TreeViewItem_KFbxNode_Parameters(const KFbxNode* pNode, HWND hTv, HTREEITEM htiParent);
void Fill_TreeView(const HWND mainHwnd);
int APIENTRY _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
HACCEL hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_UI, szWindowClass, MAX_LOADSTRING);
UIRegisterClass(hInstance);
ZeroMemory(gszInputFile, sizeof(gszInputFile) );
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_UI));
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM UIRegisterClass(
HINSTANCE hInstance
)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_UI));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = CreateSolidBrush( GetSysColor(COLOR_3DFACE) );
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_UI);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_UI));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(
HINSTANCE hInstance,
int nCmdShow
)
{
hInst = hInstance;
ghWnd = CreateWindow(
szWindowClass,
"FBX SDK SceneTreeView sample program",
WS_OVERLAPPED | WS_SYSMENU,
400,
200,
700,
800,
NULL,
NULL,
hInstance,
NULL
);
if (!ghWnd)
{
return FALSE;
}
ShowWindow(ghWnd, nCmdShow);
UpdateWindow(ghWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
int wmId, wmEvent;
switch (message)
{
case WM_CREATE:
{
CreateUIControls(hWnd);
InitializeSdkManagerAndScene();
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case READ_FROM_BUTTON:
GetInputFileName(hWnd);
Fill_TreeView(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
DestroySdkObjects(gSdkManager);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
INT_PTR CALLBACK About(
HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam
)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
{
HINSTANCE hinst = (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hDlg, GWLP_HINSTANCE);
HICON hIconFBX = (HICON) LoadImage( hinst, MAKEINTRESOURCE(IDI_UI), IMAGE_ICON, 16, 16, LR_DEFAULTSIZE);
::SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconFBX);
}
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
void CreateUIControls(
HWND hWndParent
)
{
DWORD dwStyle = WS_CHILD | WS_VISIBLE;
CreateWindowEx(
0,
"BUTTON",
"Read from ...",
dwStyle,
10,
10,
130,
30,
hWndParent,
(HMENU) READ_FROM_BUTTON,
hInst,
NULL
);
CreateWindowEx(
WS_EX_STATICEDGE,
"EDIT",
" <- select a file to read",
dwStyle|ES_AUTOHSCROLL,
150,
15,
534,
20,
hWndParent,
(HMENU) READ_FROM_EDITBOX,
hInst,
NULL
);
HFONT hf = CreateFont(
14,
6,
0,
0,
40,
0,
0,
0,
ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
0,
0,
"Arial"
);
SendMessage(GetDlgItem(hWndParent, READ_FROM_EDITBOX), WM_SETFONT, (WPARAM) hf, (LPARAM) false );
dwStyle = dwStyle | TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SHOWSELALWAYS;
CreateWindowEx(
WS_EX_STATICEDGE,
WC_TREEVIEW,
"",
dwStyle,
10,
50,
674,
686,
hWndParent,
(HMENU) FBX_TREEVIEW,
hInst,
NULL
);
}
void GetInputFileName(
HWND hWndParent
)
{
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(ofn));
char szFile[MAX_PATH];
ZeroMemory(szFile, sizeof(szFile));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hWndParent;
ofn.lpstrFile = szFile;
ofn.nMaxFile = sizeof(szFile);
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = "Select the file to read ... (use the file type filter)";
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
const char *filter = GetReaderOFNFilters();
ofn.lpstrFilter = filter;
if(GetOpenFileName(&ofn) == false)
{
delete filter;
return;
}
delete filter;
SetWindowText( GetDlgItem(hWndParent, READ_FROM_EDITBOX), szFile );
strcpy(gszInputFile, szFile);
}
HTREEITEM InsertTreeViewItem(
const HWND hTv,
const char *txt,
HTREEITEM htiParent
)
{
TVITEM tvi = {0};
tvi.mask = TVIF_TEXT|TVIF_PARAM;
tvi.pszText = (LPSTR)txt;
tvi.cchTextMax = static_cast<int>(strlen(txt));
TVINSERTSTRUCT tvis = {0};
tvis.item = tvi;
tvis.hInsertAfter = 0;
tvis.hParent = htiParent;
return reinterpret_cast<HTREEITEM>( SendMessage(hTv, TVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&tvis)) );
}
void Expand_All()
{
HWND htv = GetDlgItem(ghWnd, FBX_TREEVIEW);
if(htv == NULL) return;
Expand_All_Recurse(htv, TreeView_GetRoot(htv));
TreeView_SelectSetFirstVisible(htv, TreeView_GetRoot(htv) );
}
void Expand_All_Recurse(
HWND htv,
HTREEITEM htvi
)
{
if(htvi == NULL) return;
TreeView_Expand(htv, htvi, TVE_EXPAND);
while(htvi)
{
htvi = TreeView_GetChild(htv, htvi);
Expand_All_Recurse(htv, htvi);
while(htvi)
{
htvi = TreeView_GetNextSibling(htv, htvi);
Expand_All_Recurse(htv, htvi);
}
}
}
void DisplayHierarchy(
const HWND hTv
)
{
HTREEITEM htvi = InsertTreeViewItem(hTv, GetRootNodeName(), TVI_ROOT);
for(int i = 0; i < GetRootNode()->GetChildCount(); i++)
{
DisplayHierarchy_Recurse(GetRootNode()->GetChild(i), hTv, htvi);
}
}
void DisplayHierarchy_Recurse(
const KFbxNode* pNode,
const HWND hTv,
HTREEITEM htiParent
)
{
HTREEITEM htvi = InsertTreeViewItem(hTv, GetNodeNameAndAttributeTypeName(pNode).Buffer(), htiParent);
Add_TreeViewItem_KFbxNode_Parameters(pNode, hTv, htvi);
for(int i = 0; i < pNode->GetChildCount(); i++)
{
DisplayHierarchy_Recurse(pNode->GetChild(i), hTv, htvi);
}
}
void Add_TreeViewItem_KFbxNode_Parameters(
const KFbxNode* pNode,
HWND hTv,
HTREEITEM htiParent
)
{
if(pNode == NULL) return;
InsertTreeViewItem(hTv, GetDefaultTranslationInfo(pNode).Buffer(), htiParent);
InsertTreeViewItem(hTv, GetNodeVisibility(pNode).Buffer(), htiParent);
}
void Fill_TreeView(
const HWND mainHwnd
)
{
if(strlen(gszInputFile) == 0) return;
HWND htv = GetDlgItem(mainHwnd, FBX_TREEVIEW);
if(htv == NULL) return;
TreeView_DeleteAllItems(htv);
HCURSOR oldCursor = SetCursor( LoadCursor(NULL, IDC_WAIT) );
if(LoadFBXScene(gszInputFile) == false)
{
SetCursor(oldCursor);
return;
}
DisplayHierarchy(htv);
Expand_All();
TreeView_SelectSetFirstVisible(htv, TreeView_GetRoot(htv) );
SetCursor(oldCursor);
}