这一节是本系列文章中最重要的部分,因为CPicsiCreatorDlg类是Main子窗口的实现类,它是PicSi的功能主体。有了第2节作为基础,相信大多数朋友对CPicSiCreatorDlg的主框架是不陌生的。因此,本节将重点阐述关键思路,而代码的实现细节不在文中说明了。我会在文章的末尾将所涉及的代码贴出,若理解过程中碰到什么问题或者疑问,可随时提出。
更多详细信息请查看
java教程网
http://www.itchm.com/forum-59-1.html
CPicsiCreatorDlg与CAboutDlg一样,都是CDialogImpl的派生类。因此它也通过Create方法来创建实例对象;同时,它也有自己的消息映射,能够处理窗口消息。
题外话:可能有的朋友觉得类名CPicsiDreatorDlg太长,对的,我也觉得有点长。不过,好的命名规范是需要尽量做到见名知义的,名称长点没关系,Ctrl + C/V,一点都不慢,还不易出错。
首先看CPicsiCreatorDlg的成员变量,窗口类的成员变量一般分为两类:控制成员变量和数据成员变量。建议将它们分成两团定义,而不要交叉定义,这样可使代码更清晰一些。
控制成员变量很好理解,就是窗口中控制(控件)在类中对应的变量。我们总是通过控制成员变量来对控制加以维护的。数据成员变量是算法所需的变量,如本例中,m_fileList是一个链表,它用来保存文件名列表,而m_strOutputPath即输出路径字符串。
接下来就需要定义若干方法来响应窗口消息了。Windows编程的本质就是“以消息为基础,事件驱动之(Message based and Event driven)”。也就是说,任何一个Windows程序,它的整个生命周期说白了就是在不停地捕获消息,不停地调用方法对消息进行响应。因此,窗口类有着非常明显的特点,其主体一定是消息映射和响应方法。同时,每个类又可能含有一些成员变量以及一些私有成员方法,供消息的响应方法使用或调用。当然,它也可以拥有少量的公共方法,供父窗口调用。
每个窗口类都应该响应WM_INITDIALOG消息,窗口在被初始化时,它将被抛出,用OnInitDialog方法响应它,OnInitDialog将实现窗口相关的初始化。此外,如果窗口尺寸是可调整的话,WM_SIZE消息一般也需被处理,定义OnSize方法来响应该消息。在OnSize方法的末尾,将bHandled置为FALSE,表示WM_SIZE消息并不被当前窗口类独占,它还可以被其它窗口处理。而return 1表示允许操作系统自己再对WM_SIZE做进一步的处理,比如重绘窗口背景;如果return 0的话,操作系统是不会做进一步操作的,这对于调整窗口大小来说,可能会造成程序异常。当然,大多数消息的响应方法返回值都应该是0。
AddFile方法是CPicsiCreatorDlg类唯一一个public方法,它的作用是将szFilePath所指向的文件名添加到m_fileList链表中,并且在Listview控制中显示该文件的名称、尺寸、创建时间等信息。AddFile方法在程序中仅仅被主窗口调用,参见MainDlg::OnDropFIles方法。
接下来就是依次响应控制消息:
- IDC_BTN_SETPATH - 用户单击Set按钮,设置输出路径;
- IDC_BTN_OPEN - 用户单击Open按钮,打开输出目录;
- IDC_BTN_CLEAR - 用户单击Clear按钮,清空文件列表;
- IDC_BTN_OK - 用户单击Open按钮,开始生成内涵图;
- IDC_LIST_ORDINARY通知消息NM_DBLCLK - 用户在Listview控制中双击鼠标左键,打开选中的文件;
- IDC_LIST_ORDINARY通知消息NM_RCLICK - 用户在Listview控制右击鼠标,弹出右键菜单;
- ID_POP1_OPEN - 用户选中右键菜单项Open,打开选中的文件;
- ID_POP1_DELETE - 用户选中右键菜单项Delete,删除选中的文件;
- ID_POP1_UP - 用户选中右键菜单项Up,将选中的文件往上移一位;
- ID_POP1_DOWN - 用户选中右键菜单项Down,将选中的文件往下移一位;
- ID_POP1_TOP - 用户选中右键菜单项Top,将选中的文件置顶;
- ID_POP1_BOTTOM - 用户选中右键菜单项Bottom,将选中的文件置底。
简要说明一下CPicsiCreatorDlg类中的私有方法:
- get_appdata_path - 获得PicSi配置文件在AppData目录的全路径,配置文件里保存着输出路径(output path)。
- read_output_path - 从PicSi配置文件中读取输出路径并保存到m_strOutputPath成员变量中。
- write_output_path - 将输出路径字符串m_strOutputPath写入PicSi配置文件中。
- IsValid - 当用户单击OK按钮后,程序将首先检查文件列表是否符合规则“至少两个文件,首个文件必须是jpg文件”,只有再确认之后再正式生成内涵图。IsVaild起到检查文件列表是否符合规则的作用。
- get_rar_exe_path - 获得rar.exe文件的全路径,rar.exe用于压缩文件。
- get_copy_bat_path - 获得copy.bat文件的全路径,copy.bat包含copy命令,拼接jpg和rar文件,制作内涵图。
- get_temporary_rar_path - 获得临时rar文件的路径。
- delete_temporary_rar - 删除临时rar文件。
- build_rar_command_line - 装配rar.exe命令。
- build_copy_command_line - 装配copy命令。
- execute_subprocess - 执行子进程,传入参数即命令行字符串。
- shell_open_selected_file - 打开被选中的文件。
- refresh_list_view - 刷新Listview。
CPicSiCreatorDlg窗口类的所有代码如下所示:
// CPicsiCreatorDlg
class CPicsiCreatorDlg : public CDialogImpl<CPicsiCreatorDlg>
{
private:
CButton m_btnOK;
CButton m_btnClear;
CStatic m_static;
CEdit m_editPath;
CButton m_btnSet;
CButton m_btnOpen;
CListViewCtrl m_list;
ATL::CAtlList<WTL::CString> m_fileList;
WTL::CString m_strOutputPath;
public:
enum { IDD = IDD_DLG_CREATOR };
void AddFile(LPCTSTR szFilePath) throw()
{
ATLASSERT(szFilePath != NULL);
POSITION pos = m_fileList.GetHeadPosition();
// check if alreay added
while(pos != NULL) {
WTL::CString strFilePath = m_fileList.GetAt(pos);
if(::lstrcmpi(szFilePath, strFilePath) == 0) {
WTL::CString strMsg = _T("You have already added file \"");
strMsg += szFilePath;
strMsg += _T("\"!");
PS_MessageBox(strMsg, MB_ICONWARNING);
return;
} // end if
m_fileList.GetNext(pos);
} // end while
int nCount = m_list.GetItemCount();
WTL::CString strFilename;
PS_GetFilename(szFilePath, strFilename);
m_list.AddItem(nCount, 0, strFilename);
// add size
OFSTRUCT os;
HANDLE hFile = (HANDLE)::OpenFile(::CT2A(szFilePath), &os, OF_READ);
BY_HANDLE_FILE_INFORMATION fileinfo;
::GetFileInformationByHandle(hFile, &fileinfo);
TCHAR szSize[20];
_stprintf_s(szSize, _T("%d KB"), fileinfo.nFileSizeLow / 1024);
m_list.AddItem(nCount, 1, szSize);
// add creation time
SYSTEMTIME st;
FileTimeToSystemTime(&fileinfo.ftCreationTime, &st);
TCHAR szCreationTime[24];
_stprintf_s(szCreationTime, _T("%d/%02d/%02d %02d:%02d"), st.wYear, st.wMonth, st.wDay, (st.wHour + 8)%24, st.wMinute);
m_list.AddItem(nCount, 2, szCreationTime);
// add file
m_fileList.AddTail(szFilePath);
}
//message handler
BEGIN_MSG_MAP(CPicsiCreatorDlg)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MESSAGE_HANDLER(WM_SIZE, OnSize)
COMMAND_ID_HANDLER(IDOK, OnOK)
COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(IDC_BTN_SETPATH, OnButtonSetpath)
COMMAND_ID_HANDLER(IDC_BTN_OPEN, OnButtonOpen)
COMMAND_ID_HANDLER(IDC_BTN_CLEAR, OnButtonClear)
COMMAND_ID_HANDLER(IDC_BTN_OK, OnButtonOK)
NOTIFY_HANDLER(IDC_LIST_ORDINARY, NM_DBLCLK, OnListDoubleClick)
NOTIFY_HANDLER(IDC_LIST_ORDINARY, NM_RCLICK, OnListRightClick)
COMMAND_ID_HANDLER(ID_POP1_OPEN, OnMenuOpen)
COMMAND_ID_HANDLER(ID_POP1_DELETE, OnMenuDelete)
COMMAND_ID_HANDLER(ID_POP1_UP, OnMenuUp)
COMMAND_ID_HANDLER(ID_POP1_DOWN, OnMenuDown)
COMMAND_ID_HANDLER(ID_POP1_TOP, OnMenuTop)
COMMAND_ID_HANDLER(ID_POP1_BOTTOM, OnMenuBottom)
END_MSG_MAP()
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
m_btnOK.Attach(GetDlgItem(IDC_BTN_OK));
m_btnClear.Attach(GetDlgItem(IDC_BTN_CLEAR));
m_static.Attach(GetDlgItem(IDC_STATIC));
m_editPath.Attach(GetDlgItem(IDC_EDIT_PATH));
m_btnSet.Attach(GetDlgItem(IDC_BTN_SETPATH));
m_btnOpen.Attach(GetDlgItem(IDC_BTN_OPEN));
m_list.Attach(GetDlgItem(IDC_LIST_ORDINARY));
// add colums
LVCOLUMN lvc = { 0 };
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.fmt = LVCFMT_CENTER;
lvc.pszText = _T("File Name");
lvc.cx = 300;
m_list.InsertColumn(0, &lvc);
lvc.pszText = _T("File Size");
lvc.cx = 80;
m_list.InsertColumn(1, &lvc);
lvc.pszText = _T("Creation Time");
lvc.cx = 145;
m_list.InsertColumn(2, &lvc);
if( !read_output_path() || m_strOutputPath.GetLength() <= 0)
m_strOutputPath.Empty();
m_editPath.SetWindowText(m_strOutputPath);
return TRUE;
}
// OnSize
LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if( wParam != SIZE_MINIMIZED ) {
int nWidth = LOWORD(lParam);
int nHeight = HIWORD(lParam);
// change layout
m_static.SetWindowPos(NULL, 4, 8, 88, 16, SWP_NOACTIVATE | SWP_NOZORDER);
m_editPath.SetWindowPos(NULL, 92, 4, 228, 24, SWP_NOACTIVATE | SWP_NOZORDER);
m_btnSet.SetWindowPos(NULL, 320, 4, 22, 24, SWP_NOACTIVATE | SWP_NOZORDER);
m_btnOpen.SetWindowPos(NULL, 344, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
m_btnOK.SetWindowPos(NULL, 420, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
m_btnClear.SetWindowPos(NULL, 470, 4, 48, 24, SWP_NOACTIVATE | SWP_NOZORDER);
m_list.SetWindowPos(NULL, 0, 32, nWidth, nHeight - 32, SWP_NOACTIVATE | SWP_NOZORDER);
}
bHandled = FALSE;
return 1;
}
LRESULT OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
//EndDialog(wID);
return 0;
}
LRESULT OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
//EndDialog(wID);
return 0;
}
LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
bHandled = FALSE;
return 1;
}
LRESULT OnButtonSetpath(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CFolderDialog dlg(NULL,_T("Set Output Directory"), BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_RETURNONLYFSDIRS);
if(m_strOutputPath != _T(""))
dlg.SetInitialFolder(m_strOutputPath, TRUE);
if( dlg.DoModal() == IDOK ) {
m_strOutputPath = dlg.GetFolderPath();
m_editPath.SetWindowText(m_strOutputPath);
if( !write_output_path() )
PS_MessageBox(_T("Save output path failed!"), MB_ICONWARNING);
}
return 0;
}
LRESULT OnButtonOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
::ShellExecute(NULL, _T("open"), NULL, NULL, m_strOutputPath, SW_NORMAL);
return 0;
}
LRESULT OnButtonClear(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
m_list.DeleteAllItems();
m_fileList.RemoveAll();
return 1;
}
LRESULT OnButtonOK(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
if(m_strOutputPath.IsEmpty()) {
PS_MessageBox(_T("Output cannot be empty, set output path first!"), MB_ICONWARNING);
return 0;
}
if(!IsValid() ){
PS_MessageBox(_T("At least two files and the first one must be a *.jpg file!"), MB_ICONERROR);
return 0;
}
if( !delete_temporary_rar() ) {
PS_MessageBox(_T("Clear temporary rar file failed!"), MB_ICONERROR);
return 0;
}
WTL::CString strCommandLine;
if(!build_rar_command_line(strCommandLine)) {
PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
return 0;
}
if(!execute_subprocess(strCommandLine.GetBuffer(128))) {
PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
return 0;
}
if(!build_copy_command_line(strCommandLine)) {
PS_MessageBox(_T("Create connotative jpg failed!"), MB_ICONERROR);
delete_temporary_rar();
return 0;
}
if(!execute_subprocess(strCommandLine.GetBuffer(128))) {
delete_temporary_rar();
return 0;
}
delete_temporary_rar();
PS_MessageBox(_T("Create connotative jpg succeed!"), MB_ICONINFORMATION);
return 0;
}
LRESULT OnListDoubleClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
{
shell_open_selected_file();
return 0;
}
LRESULT OnListRightClick(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
CMenu menu;
menu.LoadMenu(IDR_MENU_POP);
CMenuHandle oMenu = menu.GetSubMenu(0);
if(nSelect == 0) {
oMenu.EnableMenuItem(ID_POP1_UP, MF_BYCOMMAND | MF_GRAYED);
oMenu.EnableMenuItem(ID_POP1_TOP, MF_BYCOMMAND | MF_GRAYED);
}
if(nSelect == m_list.GetItemCount() - 1) {
oMenu.EnableMenuItem(ID_POP1_DOWN, MF_BYCOMMAND | MF_GRAYED);
oMenu.EnableMenuItem(ID_POP1_BOTTOM, MF_BYCOMMAND | MF_GRAYED);
}
POINT pt;
::GetCursorPos(&pt);
oMenu.TrackPopupMenu(TPM_LEFTALIGN, pt.x, pt.y, m_hWnd);
return 0;
}
LRESULT OnMenuOpen(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
shell_open_selected_file();
return 0;
}
LRESULT OnMenuDelete(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; i++)
m_fileList.GetNext(pos);
m_fileList.RemoveAt(pos);
refresh_list_view();
return 0;
}
LRESULT OnMenuUp(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; i++)
m_fileList.GetNext(pos);
POSITION posPrev = pos;
m_fileList.GetPrev(posPrev);
m_fileList.SwapElements(pos, posPrev);
refresh_list_view();
return 0;
}
LRESULT OnMenuDown(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; i++)
m_fileList.GetNext(pos);
POSITION posLatter = pos;
m_fileList.GetNext(posLatter);
m_fileList.SwapElements(pos, posLatter);
refresh_list_view();
return 0;
}
LRESULT OnMenuTop(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; i++)
m_fileList.GetNext(pos);
m_fileList.MoveToHead(pos);
refresh_list_view();
return 0;
}
LRESULT OnMenuBottom(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return 0;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; i++)
m_fileList.GetNext(pos);
m_fileList.MoveToTail(pos);
refresh_list_view();
return 0;
}
private:
// get appdata path
BOOL get_appdata_path(WTL::CString& strPath) throw()
{
if(!PS_GetAppDataDirectory(strPath))
return FALSE;
PS_PathAppendBackslash(strPath);
strPath += _T("PicSi");
if( !PS_IsDirectory(strPath) ) {
if( ::CreateDirectory(strPath, NULL) == 0 )
return FALSE;
}
strPath += _T("\\cfg");
return TRUE;
}
// read output path
BOOL read_output_path() throw()
{
CString strAppdataPath;
if(!get_appdata_path(strAppdataPath))
return FALSE;
ATL::CComPtr<IStream> spStream;
HRESULT hr = ::SHCreateStreamOnFile(strAppdataPath, STGM_READ | STGM_SHARE_DENY_WRITE, &spStream);
if(FAILED(hr))
return FALSE;
ULONG nCount;
hr = spStream->Read(m_strOutputPath.GetBufferSetLength(MAX_PATH), MAX_PATH, &nCount);
m_strOutputPath.ReleaseBuffer();
if(FAILED(hr))
return FALSE;
return TRUE;
}
// write output path
BOOL write_output_path() throw()
{
CString strAppdataPath;
if(!get_appdata_path(strAppdataPath))
return FALSE;
ATL::CComPtr<IStream> spStream;
HRESULT hr = ::SHCreateStreamOnFile(strAppdataPath, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, &spStream);
if(FAILED(hr))
return FALSE;
ULONG nCount;
hr = spStream->Write(m_strOutputPath, MAX_PATH, &nCount);
if(FAILED(hr))
return FALSE;
return TRUE;
}
// check valid
BOOL IsValid() throw()
{
int nCount = m_list.GetItemCount();
if(nCount < 2)
return FALSE;
TCHAR szText[MAX_PATH];
int nTotal = m_list.GetItemText(0, 0, szText, MAX_PATH);
WTL::CString strPath = szText;
strPath.MakeLower();
int nPos = strPath.Find(_T(".jpg"));
if(nPos < 0 || nPos < nTotal - 4)
return FALSE;
return TRUE;
}
// get rar exe path
BOOL get_rar_exe_path(WTL::CString& strRarExePath) throw()
{
if(!PS_GetInstallationDirectory(strRarExePath))
return FALSE;
else {
if(!PS_PathAppendBackslash(strRarExePath))
return FALSE;
strRarExePath += _T("Rar.exe");
}
return TRUE;
}
// get copy bat path
BOOL get_copy_bat_path(WTL::CString& strCopyBatPath) throw()
{
if(!PS_GetInstallationDirectory(strCopyBatPath))
return FALSE;
else {
if(!PS_PathAppendBackslash(strCopyBatPath))
return FALSE;
strCopyBatPath += _T("copy.bat");
}
return TRUE;
}
// get temporary rar path
BOOL get_temporary_rar_path(WTL::CString& strPath) throw()
{
strPath = m_strOutputPath;
if(!PS_PathAppendBackslash(strPath))
return FALSE;
strPath += _T("picsi_temporary.rar");
return TRUE;
}
// delete temporary rar
BOOL delete_temporary_rar() throw()
{
WTL::CString strRarPath;
get_temporary_rar_path(strRarPath);
if( ::DeleteFile(strRarPath) == 0 && ::GetLastError() != ERROR_FILE_NOT_FOUND)
return FALSE;
return TRUE;
}
// build command line
BOOL build_rar_command_line(WTL::CString& strCmd) throw()
{
if( !get_rar_exe_path(strCmd) )
return FALSE;
PS_AddDoubleQuotationMarks(strCmd);
strCmd += _T(" a -ep1 ");
WTL::CString strRarPath;
if( !get_temporary_rar_path(strRarPath) )
return FALSE;
PS_AddDoubleQuotationMarks(strRarPath);
strCmd += strRarPath;
// append source file name
WTL::CString strTmp;
POSITION pos = m_fileList.GetHeadPosition();
m_fileList.GetNext(pos);
while(pos != NULL) {
strTmp = m_fileList.GetAt(pos);
PS_AddDoubleQuotationMarks(strTmp);
strCmd += _T(" ");
strCmd += strTmp;
m_fileList.GetNext(pos);
}
return TRUE;
}
// build copy command line
BOOL build_copy_command_line(WTL::CString& strCmd) throw()
{
if( !get_copy_bat_path(strCmd) )
return FALSE;
PS_AddDoubleQuotationMarks(strCmd);
strCmd += _T(" ");
// append jpg file
WTL::CString strJpgPath = m_fileList.GetHead();
PS_AddDoubleQuotationMarks(strJpgPath);
strCmd += strJpgPath;
strCmd += _T(" ");
// append rar file
WTL::CString strRarPath;
if( !get_temporary_rar_path(strRarPath) )
return FALSE;
PS_AddDoubleQuotationMarks(strRarPath);
strCmd += strRarPath;
strCmd += _T(" ");
// append result file
WTL::CString strResultFile;
TCHAR szFilename[MAX_PATH];
m_list.GetItemText(0, 0, szFilename, MAX_PATH);
PS_GetFilename(szFilename, strResultFile);
PS_PathAppendBackslash(m_strOutputPath);
strResultFile = m_strOutputPath + strResultFile;
PS_AddDoubleQuotationMarks(strResultFile);
strCmd += strResultFile;
return TRUE;
}
// execute subprocess
BOOL execute_subprocess(LPTSTR szCommandLine) throw()
{
ATLASSERT(szCommandLine != NULL);
STARTUPINFO si = { 0 };
si.cb = sizeof(si);
PROCESS_INFORMATION pi = { 0 };
if( !CreateProcess( NULL, szCommandLine,
NULL, NULL, FALSE, CREATE_NO_WINDOW,
NULL, NULL, &si, &pi ) ) {
DWORD dwCode = ::GetLastError();
return FALSE;
}
WaitForSingleObject( pi.hProcess, INFINITE );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
return TRUE;
}
// shell open selected file
void shell_open_selected_file() throw()
{
int nSelect = m_list.GetSelectedIndex();
if(nSelect < 0)
return;
POSITION pos = m_fileList.GetHeadPosition();
for(int i = 0; i < nSelect; ++i)
m_fileList.GetNext(pos);
::ShellExecute(NULL, _T("open"), m_fileList.GetAt(pos), NULL, NULL, SW_NORMAL);
}
// refresh list view
void refresh_list_view() throw()
{
m_list.DeleteAllItems();
POSITION pos = m_fileList.GetHeadPosition();
WTL::CString strFilePath;
int i = 0;
while(pos != NULL) {
strFilePath = m_fileList.GetAt(pos);
WTL::CString strFilename;
PS_GetFilename(strFilePath, strFilename);
m_list.AddItem(i, 0, strFilename);
// add size
OFSTRUCT os;
HANDLE hFile = (HANDLE)::OpenFile(::CT2A(strFilePath), &os, OF_READ);
BY_HANDLE_FILE_INFORMATION fileinfo;
::GetFileInformationByHandle(hFile, &fileinfo);
TCHAR szSize[20];
_stprintf_s(szSize, _T("%d KB"), fileinfo.nFileSizeLow / 1024);
m_list.AddItem(i, 1, szSize);
// add creation time
SYSTEMTIME st;
FileTimeToSystemTime(&fileinfo.ftCreationTime, &st);
TCHAR szCreationTime[24];
_stprintf_s(szCreationTime, _T("%d/%02d/%02d %02d:%02d"), st.wYear, st.wMonth, st.wDay, (st.wHour + 8) % 24, st.wMinute);
m_list.AddItem(i, 2, szCreationTime);
i++;
m_fileList.GetNext(pos);
}
}
};