Artifact Content

Not logged in

Artifact fcaa4b48ba621d24c91cb8fc4f69fc4ff092b925


     1  
     2  #include "stdafx.h"
     3  #include "NoahApp.h"
     4  #include "SubDlg.h"
     5  
     6  int CArcViewDlg::st_nLife;
     7  
     8  BOOL CArcViewDlg::onInit()
     9  {
    10  	char cstr[100];
    11  	kiStr str;
    12  	kiPath path;
    13  	SHFILEINFO sfi,lfi;
    14  	HIMAGELIST hImS,hImL;
    15  	kiListView ctrl( this, IDC_FILELIST );
    16  	__int64 filesize_sum = 0;
    17  
    18  	//-- ダイアログ一個生成の印
    19  	hello();
    20  	m_bSmallFirst[0] = m_bSmallFirst[1] = m_bSmallFirst[2] =
    21  	m_bSmallFirst[3] = m_bSmallFirst[4] = m_bSmallFirst[5] = true;
    22  
    23  	//-- 真ん中に&前に
    24  	setCenter( hwnd(), app()->mainhwnd() );
    25  	setFront( hwnd() );
    26  
    27  	//-- アイコン
    28  	path = m_fname.basedir, path += m_fname.sname;
    29  	hImS = (HIMAGELIST)::SHGetFileInfo( path, 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_SMALLICON );
    30  	hImL = (HIMAGELIST)::SHGetFileInfo( path, 0, &lfi, sizeof(lfi), SHGFI_SYSICONINDEX | SHGFI_ICON | SHGFI_LARGEICON );
    31  	sendMsg( WM_SETICON, ICON_BIG,   (LPARAM)lfi.hIcon );
    32  	sendMsg( WM_SETICON, ICON_SMALL, (LPARAM)sfi.hIcon );
    33  
    34  	//-- タイトル
    35  	sendMsg( WM_SETTEXT, 0, (LPARAM)kiPath(m_fname.lname).name() );
    36  
    37  	//-- 解凍先
    38  	sendMsgToItem( IDC_DDIR, WM_SETTEXT, 0, (LPARAM)(const char*)m_ddir );
    39  
    40  	//-- リスト
    41  	if( !m_pArc->list( m_fname, m_files ) || m_files.len()==0 )
    42  	{
    43  		m_bAble = false;
    44  		ctrl.insertColumn( 0, "", 510 );
    45  		ctrl.insertItem( 0, str.loadRsrc(IDS_NOLIST) );
    46  	}
    47  	else
    48  	{
    49  		m_bAble = ( 0 != (m_pArc->ability() & aMeltEach) );
    50  
    51  		ctrl.setImageList( hImL, hImS );
    52  		ctrl.insertColumn( 0, str.loadRsrc(IDS_FNAME),   110 );
    53  		ctrl.insertColumn( 1, str.loadRsrc(IDS_SIZE),    70,  LVCFMT_RIGHT );
    54  		ctrl.insertColumn( 2, str.loadRsrc(IDS_DATETIME),100, LVCFMT_RIGHT );
    55  		ctrl.insertColumn( 3, str.loadRsrc(IDS_RATIO),   55,  LVCFMT_RIGHT );
    56  		ctrl.insertColumn( 4, str.loadRsrc(IDS_METHOD),  50,  LVCFMT_RIGHT );
    57  		ctrl.insertColumn( 5, str.loadRsrc(IDS_PATH),    130 );
    58  
    59  		FILETIME ftm;
    60  		SYSTEMTIME stm;
    61  
    62  		//-- アイテム
    63  		for( unsigned int i=0,k=0; i!=m_files.len(); i++ )
    64  			if( m_files[i].isfile )
    65  			{
    66  #define			usiz (m_files[i].inf.dwOriginalSize)
    67  #define			csiz (m_files[i].inf.dwCompressedSize)
    68  #define			method (m_files[i].inf.szMode)
    69  #define			date (m_files[i].inf.wDate)
    70  #define			time (m_files[i].inf.wTime)
    71  				path = m_files[i].inf.szFileName;
    72  
    73  				// ファイル名
    74  				ctrl.insertItem( k, path.name(),
    75  					(LPARAM)(&m_files[i]), kiSUtil::getSysIcon(path.ext()) );
    76  
    77  				// サイズ
    78  				if( usiz == 0xffffffff )
    79  					ctrl.setSubItem( k, 1, "????" );
    80  				else
    81  					ctrl.setSubItem( k, 1, str.setInt( usiz,true ) );
    82  
    83  				// 時間
    84  				if( ::DosDateTimeToFileTime( date, time, &ftm )
    85  				 && ::FileTimeToSystemTime( &ftm, &stm ) )
    86  				{
    87  					*cstr=0;
    88  					::GetDateFormat( LOCALE_USER_DEFAULT, 0, &stm,
    89  									 "yy/MM/dd", cstr, sizeof(cstr) );
    90  					str=cstr;
    91  					::GetTimeFormat( LOCALE_USER_DEFAULT, 0, &stm,
    92  									 " HH:mm", cstr, sizeof(cstr) );
    93  					str+=cstr;
    94  					ctrl.setSubItem( k, 2, str );
    95  				}
    96  
    97  				// 圧縮率
    98  				filesize_sum += usiz;
    99  				if( usiz==0 )		ctrl.setSubItem( k, 3, "100%" );
   100  				else if( csiz==0 )	ctrl.setSubItem( k, 3, "????" );
   101  				else				ctrl.setSubItem( k, 3, str.setInt( (int)(((__int64)csiz)*100/usiz) )+='%' );
   102  
   103  				// メソッド
   104  				ctrl.setSubItem( k, 4, method );
   105  
   106  				// パス
   107  				path.beDirOnly();
   108  				ctrl.setSubItem( k, 5, path );
   109  
   110  				k++;
   111  
   112  #undef			usiz
   113  #undef			csiz
   114  #undef			method
   115  #undef			date
   116  #undef			time
   117  			}
   118  
   119  		//-- ドラッグ&ドロップフォーマット登録
   120  		FORMATETC fmt;
   121  		fmt.cfFormat = CF_HDROP;
   122  		fmt.ptd      = NULL;
   123  		fmt.dwAspect = DVASPECT_CONTENT;
   124  		fmt.lindex   = -1;
   125  		fmt.tymed    = TYMED_HGLOBAL;
   126  		addFormat( fmt );
   127  	}
   128  
   129  	//-- 情報 --
   130  	char tmp[255];
   131  	kiStr full_filename = m_fname.basedir + m_fname.lname;
   132  	__int64 filesize_arc = kiFile::getSize64(full_filename);
   133  	if( filesize_sum==0 ) filesize_sum = 1;
   134  	wsprintf( tmp, kiStr().loadRsrc(IDS_ARCVIEW_MSG),
   135  		m_files.len(),
   136  		(int)(filesize_arc*100 / filesize_sum),
   137  		(const char*)m_pArc->arctype_name(full_filename)
   138  	);
   139  	sendMsgToItem( IDC_STATUSBAR, WM_SETTEXT, 0, (long)tmp );
   140  
   141  	if( !m_bAble )
   142  	{
   143  		static const UINT items[] = { IDC_SELECTINV,IDC_REF,IDC_MELTEACH,IDC_SHOW,IDC_DDIR };
   144  		for( int i=0; i!=sizeof(items)/sizeof(UINT); i++ )
   145  			::EnableWindow( item(items[i]), FALSE );
   146  	}
   147  
   148  	return FALSE;
   149  }
   150  
   151  bool CArcViewDlg::onOK()
   152  {
   153  	setdir();
   154  	m_pArc->melt( m_fname, m_ddir );
   155  	myapp().open_folder( m_ddir, 1 );
   156  	kiSUtil::switchCurDirToExeDir(); // 念のため
   157  	return onCancel();
   158  }
   159  
   160  bool CArcViewDlg::onCancel()
   161  {
   162  	::SetCurrentDirectory( m_fname.basedir );
   163  	m_tdir.remove();
   164  	if( kiSUtil::exist(m_tdir) )
   165  	{
   166  		kiStr tmp(600);
   167  		if( IDNO==app()->msgBox( tmp.loadRsrc(IDS_EXECUTING), NULL, MB_YESNO|MB_DEFBUTTON2 ) )
   168  			return false;
   169  	}
   170  
   171  	kiListView(this,IDC_FILELIST).setImageList( NULL, NULL );
   172  	byebye();
   173  	return true;
   174  }
   175  
   176  bool CArcViewDlg::giveData( const FORMATETC& fmt, STGMEDIUM* stg, bool firstcall )
   177  {
   178  	if( firstcall )
   179  		if( 0x8000<=m_pArc->melt( m_fname, m_tdir, &m_files ) )
   180  			return false;
   181  
   182  	unsigned int i;
   183  	BOOL fWide = (app()->osver().dwPlatformId==VER_PLATFORM_WIN32_NT);
   184  	kiArray<kiPath> lst;
   185  	kiPath tmp;
   186  	int flen = 0;
   187  	wchar_t wbuf[600];
   188  
   189  	for( i=0; i!=m_files.len(); i++ )
   190  		if( m_files[i].selected )
   191  		{
   192  			tmp = m_tdir;
   193  			tmp += m_files[i].inf.szFileName;
   194  
   195  			lst.add( tmp );
   196  			if( fWide )
   197  				flen += (::MultiByteToWideChar( CP_ACP, 0, tmp, -1, wbuf, 600 )+1)*2;
   198  			else
   199  				flen += (tmp.len()+1);
   200  		}
   201  
   202  	HDROP hDrop = (HDROP)::GlobalAlloc( GHND, sizeof(DROPFILES)+flen+1 );
   203  
   204  	DROPFILES* dr = (DROPFILES*)::GlobalLock( hDrop );
   205  	dr->pFiles = sizeof(DROPFILES);
   206  	dr->pt.x   = dr->pt.y = 0;
   207  	dr->fNC    = FALSE;
   208  	dr->fWide  = fWide;
   209  
   210  	char* buf = (char*)(&dr[1]);
   211  	for( i=0; i!=lst.len(); i++ )
   212  	{
   213  		if( fWide )
   214  		{
   215  			flen = ::MultiByteToWideChar( CP_ACP, 0, lst[i], -1, wbuf, 600 );
   216  			ki_memcpy( buf, wbuf, flen*2 );
   217  			for( int k=0; k!=flen; k++ )
   218  				if( ((wchar_t*)buf)[k] == '/' )
   219  					((wchar_t*)buf)[k] = '\\';
   220  			buf += flen*2;
   221  		}
   222  		else
   223  		{
   224  			ki_strcpy( buf,lst[i] );
   225  			for( int k=0; k!=lst[i].len(); k++ )
   226  				if( buf[k] == '/' )
   227  					buf[k] = '\\';
   228  			buf += lst[i].len() + 1;
   229  		}
   230  	}
   231  	*buf=0;
   232  	if( fWide )
   233  		buf[1]='\0';
   234  
   235  	::GlobalUnlock( hDrop );
   236  
   237  	stg->hGlobal        = hDrop;
   238  	stg->tymed          = TYMED_HGLOBAL;
   239  	stg->pUnkForRelease = NULL;
   240  	return true;
   241  }
   242  
   243  BOOL CALLBACK CArcViewDlg::proc( UINT msg, WPARAM wp, LPARAM lp )
   244  {
   245  	switch( msg )
   246  	{
   247  	//-- メインウインドウ指定 ---------------------
   248  	case WM_ACTIVATE:
   249  		if( LOWORD(wp)==WA_ACTIVE || LOWORD(wp)==WA_CLICKACTIVE )
   250  		{
   251  			app()->setMainWnd( this );
   252  			return TRUE;
   253  		}
   254  		break;
   255  
   256  	//-- リサイズ関連の処理 ---------------------
   257  	case WM_GETMINMAXINFO:
   258  		{
   259  			RECT self,child;
   260  			::GetWindowRect( hwnd(), &self );
   261  			::GetWindowRect( item(IDC_REF), &child );
   262  			POINT& sz = ((MINMAXINFO*)lp)->ptMinTrackSize;
   263  			sz.x = child.right - self.left + 18;
   264  			sz.y = child.bottom - self.top + 100;
   265  		}
   266  		return TRUE;
   267  	case WM_SIZE:
   268  		if( wp!=SIZE_MAXHIDE && wp!=SIZE_MINIMIZED )
   269  		{
   270  			RECT self,ref,child,sbar;
   271  			::GetWindowRect( hwnd(), &self );
   272  			::GetWindowRect( item(IDC_REF), &ref );
   273  			::GetWindowRect( item(IDC_FILELIST), &child );
   274  			::GetClientRect( item(IDC_STATUSBAR), &sbar );
   275  
   276  			::SetWindowPos( item(IDC_FILELIST), NULL, 0, 0,
   277  				LOWORD(lp),
   278  				(self.bottom-ref.bottom)-(child.top-ref.bottom)
   279  				-(sbar.bottom-sbar.top)-10,
   280  				SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER );
   281  
   282  			::GetClientRect( hwnd(), &self );
   283  			::SetWindowPos( item(IDC_STATUSBAR), NULL, sbar.left,
   284  				self.bottom - (sbar.bottom-sbar.top),
   285  				0, 0, SWP_NOSIZE|SWP_NOOWNERZORDER|SWP_NOZORDER );
   286  		}
   287  		break;
   288  
   289  	case WM_NOTIFY:
   290  		if( wp==IDC_FILELIST && m_bAble )
   291  		{
   292  			NMHDR* phdr=(NMHDR*)lp;
   293  			if( phdr->code==LVN_BEGINDRAG || phdr->code==LVN_BEGINRDRAG )
   294  			{
   295  				if( setSelection() )
   296  					kiDropSource::DnD( this, DROPEFFECT_COPY );
   297  				return TRUE;
   298  			}
   299  			else if( phdr->code==LVN_COLUMNCLICK )
   300  				DoSort( ((NMLISTVIEW*)lp)->iSubItem );
   301  			else if( phdr->code==NM_DBLCLK )
   302  				sendMsg( WM_COMMAND, IDC_SHOW );
   303  			else if( phdr->code==NM_RCLICK )
   304  			{
   305  				if( setSelection() )
   306  					DoRMenu();
   307  			}
   308  		}
   309  		break;
   310  
   311  	case WM_COMMAND:
   312  		switch( LOWORD(wp) )
   313  		{
   314  		case IDC_SELECTINV: // 選択反転
   315  			{
   316  				LVITEM item;
   317  				item.mask = LVIF_STATE;
   318  				item.stateMask = LVIS_SELECTED;
   319  				int j,m=sendMsgToItem( IDC_FILELIST, LVM_GETITEMCOUNT );
   320  				for( j=0; j!=m; j++ )
   321  				{
   322  					item.state = ~sendMsgToItem( IDC_FILELIST, LVM_GETITEMSTATE, j, LVIS_SELECTED );
   323  					sendMsgToItem( IDC_FILELIST, LVM_SETITEMSTATE, j, (LPARAM)&item );
   324  				}
   325  				::SetFocus( this->item(IDC_FILELIST) );
   326  			}
   327  			return TRUE;
   328  
   329  		case IDC_REF: // 解凍先設定
   330  			kiSUtil::getFolderDlgOfEditBox( item(IDC_DDIR), hwnd(), kiStr().loadRsrc(IDS_CHOOSEDIR) );
   331  			return TRUE;
   332  
   333  		case IDC_MELTEACH: // 一部解凍
   334  			if( setSelection() )
   335  			{
   336  				setdir();
   337  				int result = m_pArc->melt( m_fname, m_ddir, &m_files );
   338  				if( result<0x8000 )
   339  					myapp().open_folder( m_ddir, 1 );
   340  				else if( result != 0x8020 )
   341  				{
   342  					char str[255];
   343  					wsprintf( str, "%s\nError No: [%x]",
   344  						(const char*)kiStr().loadRsrc( IDS_M_ERROR ), result );
   345  					app()->msgBox( str );
   346  				}
   347  				kiSUtil::switchCurDirToExeDir(); // 念のため
   348  			}
   349  			return TRUE;
   350  
   351  		case IDC_SHOW: // 表示
   352  			if( setSelection() )
   353  			{
   354  				int assocCnt = hlp_cnt_check();
   355  				if( 0x8000 > m_pArc->melt( m_fname, m_tdir, &m_files ) )
   356  				{
   357  					if( assocCnt != -1 )
   358  						m_files[assocCnt].selected = false;
   359  					for( unsigned i=0; i!=m_files.len(); i++ )
   360  						if( m_files[i].selected )
   361  						{
   362  							kiPath tmp(m_tdir);
   363  							char yen[MAX_PATH];
   364  							ki_strcpy( yen, m_files[i].inf.szFileName );
   365  							for( char* p=yen; *p; p=kiStr::next(p) )
   366  								if( *p=='/' )
   367  									*p = '\\';
   368  							tmp += yen;
   369  							::ShellExecute( hwnd(), NULL, tmp, NULL, m_tdir, SW_SHOWDEFAULT );
   370  						}
   371  				}
   372  				kiSUtil::switchCurDirToExeDir(); // 念のため
   373  			}
   374  			return TRUE;
   375  		}
   376  	}
   377  	return FALSE;
   378  }
   379  
   380  int CArcViewDlg::hlp_cnt_check()
   381  {
   382  	// 一個目の選択済みファイルが .hlp か否か
   383  	for( unsigned i=0; i!=m_files.len(); i++ )
   384  		if( m_files[i].selected )
   385  			break;
   386  	if( i==m_files.len() )
   387  		return -1;
   388  	int x = kiPath::ext(m_files[i].inf.szFileName)-m_files[i].inf.szFileName;
   389  	if( 0!=ki_strcmpi( "hlp", m_files[i].inf.szFileName+x ) )
   390  		return -1;
   391  
   392  	// .cnt のファイル名
   393  	char cntpath[FNAME_MAX32];
   394  	ki_strcpy( cntpath, m_files[i].inf.szFileName );
   395  	cntpath[x]='c', cntpath[x+1]='n', cntpath[x+2]='t';
   396  
   397  	// .cntも一時的に選択する
   398  	for( i=0; i!=m_files.len(); i++ )
   399  		if( 0==ki_strcmpi( cntpath, m_files[i].inf.szFileName ) )
   400  		{
   401  			if( m_files[i].selected )
   402  				return -1;
   403  			m_files[i].selected = true;
   404  			return i;
   405  		}
   406  	return -1;
   407  }
   408  
   409  int CALLBACK CArcViewDlg::lv_compare( LPARAM p1, LPARAM p2, LPARAM type )
   410  {
   411  	bool rev = false;
   412  	if( type>=10000 )
   413  		rev=true, type-=10000;
   414  	int ans = 0;
   415  
   416  	INDIVIDUALINFO *a1=&((arcfile*)p1)->inf, *a2=&((arcfile*)p2)->inf;
   417  	switch( type )
   418  	{
   419  	case 0: //NAME
   420  		ans = ::lstrcmp( kiPath::name(a1->szFileName),
   421  			             kiPath::name(a2->szFileName) );
   422  		break;
   423  	case 1: //SIZE
   424  		ans = (signed)a1->dwOriginalSize - (signed)a2->dwOriginalSize;
   425  		break;
   426  	case 2: //DATE,TIME
   427  		ans = (signed)a1->wDate - (signed)a2->wDate;
   428  		if( ans==0 )
   429  			ans = (signed)a1->wTime - (signed)a2->wTime;
   430  		break;
   431  	case 3:{//RATIO
   432  		int cr1, cr2;
   433  		if( a1->dwOriginalSize==0 )        cr1=100;
   434  		else if( a1->dwCompressedSize==0 ) cr1=-1;
   435  		else cr1 = (a1->dwCompressedSize*100)/(a1->dwOriginalSize);
   436  		if( a2->dwOriginalSize==0 )        cr2=100;
   437  		else if( a2->dwCompressedSize==0 ) cr2=-1;
   438  		else cr2 = (int)((((__int64)a2->dwCompressedSize)*100)/(a2->dwOriginalSize));
   439  		ans = cr1 - cr2;
   440  		}break;
   441  	case 4: //METHOD
   442  		ans = ::lstrcmp( a1->szMode, a2->szMode );
   443  		break;
   444  	case 5:{//PATH
   445  		kiPath pt1(a1->szFileName), pt2(a2->szFileName);
   446  		pt1.beDirOnly(), pt2.beDirOnly();
   447  		ans = ::lstrcmp( pt1, pt2 );
   448  		}break;
   449  	}
   450  
   451  	return rev ? -ans : ans;
   452  }
   453  
   454  void CArcViewDlg::DoSort( int col )
   455  {
   456  	WPARAM p = col + (m_bSmallFirst[col] ? 0 : 10000);
   457  	sendMsgToItem( IDC_FILELIST, LVM_SORTITEMS, p, (LPARAM)lv_compare );
   458  	m_bSmallFirst[col] = !m_bSmallFirst[col];
   459  }
   460  
   461  void CArcViewDlg::GenerateDirMenu( HMENU m, int& id, StrArray* sx, const kiPath& pth )
   462  {
   463  	// フォルダ内リストアップ
   464  	kiFindFile ff;
   465  	ff.begin( kiPath(pth)+="*" );
   466  	for( WIN32_FIND_DATA fd; ff.next(&fd); )
   467  		if( fd.cFileName[0]!='.'
   468  		 && !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) )
   469  		{
   470  			kiPath fullpath(pth); fullpath+=fd.cFileName;
   471  			const int pID=id;
   472  			MENUITEMINFO mi = { sizeof(MENUITEMINFO) };
   473  
   474  			if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
   475  			{
   476  				// 再帰的に
   477  				mi.fMask = MIIM_SUBMENU | 0x00000040;// (MIIM_STRING)
   478  				mi.hSubMenu = ::CreatePopupMenu();
   479  				GenerateDirMenu( mi.hSubMenu, id, sx,
   480  					kiPath(kiPath(fullpath)+="\\") );
   481  			}
   482  			else
   483  			{
   484  				const char* ext = kiPath::ext(fd.cFileName);
   485  				if( ::lstrlen(ext) > 4 ) continue;
   486  				if( 0==::lstrcmpi(ext,"lnk") )
   487  					*const_cast<char*>(ext-1) = '\0';
   488  				mi.fMask = MIIM_ID | 0x00000040;// (MIIM_STRING)
   489  				mi.wID = id++;
   490  				sx->add( fullpath );
   491  			}
   492  
   493  			mi.dwTypeData = const_cast<char*>((const char*)fd.cFileName);
   494  			mi.cch        = ::lstrlen(fd.cFileName);
   495  			::InsertMenuItem( m, pID, FALSE, &mi );
   496  		}
   497  }
   498  
   499  void CArcViewDlg::DoRMenu()
   500  {
   501  	// メニュー作成
   502  	HMENU m = ::CreatePopupMenu();
   503  	POINT pt; ::GetCursorPos( &pt );
   504  	const int IDSTART = 128;
   505  
   506  	// フォルダの中身をリストアップしつつメニューに追加
   507  	int id = IDSTART;
   508  	StrArray lst;
   509  	GenerateDirMenu( m, id, &lst, kiPath(CSIDL_SENDTO) );
   510  
   511  	// メニュー表示
   512  	id = ::TrackPopupMenu( m,
   513  		TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RETURNCMD|TPM_NONOTIFY,
   514  		pt.x, pt.y, 0, hwnd(), NULL );
   515  	::DestroyMenu( m );
   516  
   517  	// 結果処理
   518  	if( id != 0 )
   519  	{
   520  		kiStr cmd;
   521  		if( 0x8000>m_pArc->melt( m_fname, m_tdir, &m_files ) )
   522  		{
   523  			for( UINT i=0; i!=m_files.len(); i++ )
   524  				if( m_files[i].selected )
   525  				{
   526  					cmd += "\"";
   527  					cmd += m_tdir;
   528  					const char* buf = m_files[i].inf.szFileName;
   529  					for( int k=0; buf[k]; ++k )
   530  						cmd += ( buf[k]=='/' ? '\\' : buf[k] );
   531  					cmd += "\" ";
   532  				}
   533  			ShellExecute(hwnd(),NULL,lst[id-IDSTART],cmd,NULL,SW_SHOW);
   534  		}
   535  	}
   536  }
   537