⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellctxmenu.cpp

📁 加密技术VC++
💻 CPP
字号:
#include "stdafx.h"
#include "resource.h"
#include "priv.h"
#include "ShellExt.h"
#include "CtxMenu.h"

#include <shlobj.h>
#include <shlguid.h>
#include "io.h"

// utilities
#include "ShUtils.h"
#include "FileProcess.h"
#include "CancelDlg.h"              

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/*----------------------------------------------------------------

  FUNCTION: CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO)

  PURPOSE: Called by the shell after the user has selected on of the
           menu items that was added in QueryContextMenu(). This is 
           the function where you get to do your real work!!!

  PARAMETERS:
    lpcmi - Pointer to an CMINVOKECOMMANDINFO structure

  RETURN VALUE:


  COMMENTS:
 
----------------------------------------------------------------*/

STDMETHODIMP CShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
	// look at all the MFC stuff in here! call this to allow us to 
	// not blow up when we try to use it.
	AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

	HINSTANCE hInst = AfxGetInstanceHandle();

    ODS("CShellExt::InvokeCommand()\r\n");

	HWND hParentWnd = lpcmi->hwnd;
                                      
	HRESULT hr = NOERROR;

    //If HIWORD(lpcmi->lpVerb) then we have been called programmatically
    //and lpVerb is a command that should be invoked.  Otherwise, the shell
    //has called us, and LOWORD(lpcmi->lpVerb) is the menu ID the user has
    //selected.  Actually, it's (menu ID - idCmdFirst) from QueryContextMenu().
	UINT idCmd = 0;

	if (!HIWORD(lpcmi->lpVerb)) 
	{
		idCmd = LOWORD(lpcmi->lpVerb);

		BOOL bEncrypt = FALSE;
		// process it
		switch (idCmd) 
		{
		default:
		case 0: // Encrypt
			bEncrypt = TRUE;

		case 1: // Decrypt
			{
	            // get a CWnd for Explorer
				CWnd *pParentWnd = NULL;
				if (hParentWnd!=NULL)
					pParentWnd = CWnd::FromHandle(hParentWnd);

		        // disable explorer
				::PostMessage(hParentWnd, WM_ENABLE, (WPARAM)FALSE, (LPARAM)0);

		        // create our process/cancel dialog
				CCancelDlg *pCancel;
				try {
					pCancel = new CCancelDlg;
				} 
				catch (CMemoryException *e) {
					e->ReportError();
					e->Delete();
					pCancel=NULL;
					return hr;
				}

				// show it
				pCancel->Create(pParentWnd);
				if (::IsWindow(pCancel->m_hWnd)) {
					pCancel->ShowWindow(SW_SHOW);
				}

				int iFiles = m_csaPaths.GetSize();

				// wrap this whole thing in a nice try/catch
				try {

					// Start the AVI
					pCancel->StartAVI();

					// do it!
					for (int i=0; i < iFiles; i++) {

						// get the current file. this array is filled in CShellExt::Initialize
						CString csFile = m_csaPaths.GetAt(i);

						CString csFPathDots = _T("");

						// Check if the path is bigger that 32 bytes
						if (csFile.GetLength() > 32) {

							CStringArray csaPathInfo;
							
							pCancel->Split(csFile, "\\", csaPathInfo, FALSE);

							csFPathDots = csaPathInfo.GetAt(0) + "\\";
							csFPathDots += csaPathInfo.GetAt(1);
							csFPathDots += "\\...\\";
							csFPathDots += csaPathInfo.GetAt(csaPathInfo.GetUpperBound());

							// Now that we have a pathe with dots...
							//
							// Check (again) if the path is bigger that 32 bytes
							if (csFPathDots.GetLength() > 32) {
								csFPathDots = csaPathInfo.GetAt(0);
								csFPathDots += "\\...\\";
								csFPathDots += csaPathInfo.GetAt(csaPathInfo.GetUpperBound());
							}
						}
						else {
							// The path is smaller that 32 bytes...so use it!
							csFPathDots = csFile;
						}

						// update progress dialog
						pCancel->SetPathText(csFPathDots);

						// move some Windows messages around
						ShMsgPump();

						ThreadInfo is;
						is.bDone = FALSE;
						is.bStop = FALSE;
						is.csFile = csFile;
						is.bEncrypt = bEncrypt;

						if (pCancel->IsDirectory(csFile))
							is.bDir = TRUE;
						else
							is.bDir = FALSE;

						// this struct carries info to and from the thread

						//////////////////////////////////////////////////////
						// start the worker thread
						CWinThread *pThread = AfxBeginThread(FileProcessThreadFunc, 
															(LPVOID)&is,
															THREAD_PRIORITY_NORMAL,
															0,
															CREATE_SUSPENDED);

						//////////////////////////////////////////////////////
						// did we create OK?
						if (pThread ==NULL) {
							ODS("Thread creation falied\n");
							break;
						}

						//////////////////////////////////////////////////////
						// start doing some real work

						// this will start the thread for real. 
						if (pThread->ResumeThread()==-1) {
							ODS("Resume thread failure\n");
							break;
						}
						
						BOOL bCancel = FALSE;
						BOOL bDone = FALSE;

						//////////////////////////////////////////////////////
						// now, we just sit back and wait
						// for the thread to signal finished

						while (!bDone) {
							// test for cancel signal from the progress dialod
							bCancel = GET_SAFE(pCancel->m_bCancel);
							if (bCancel) {
								ODS("bCancel (main)\n");
								SET_SAFE(is.bStop, TRUE);
							}

							// test for thread finished
							bDone = GET_SAFE(is.bDone);

							// let the dialog breathe
							ShMsgPump();
						}

						ODS("bDone (main)\n");

						// operation cancelled. abort the whole thing...
						if (bCancel) {
							ODS("cancelled (main)\n");
							break;
						}

						// handle any errors that may have popped up
						int iErr = GET_SAFE(is.iErr);

						if (iErr!=0) {

							CString msg;

							pCancel->ShowWindow(SW_HIDE);

							msg.Format("Error : %d", iErr);


							UINT res = AfxMessageBox(SHELLEXNAME + msg, MB_OKCANCEL);

							// if the user presses 'cancel', abort
							if (res==IDCANCEL)
								break;

							// bring back our progress dialog
							pCancel->ShowWindow(SW_SHOW);

						} // err

					} // file loop
				} 
				catch (CException *e) {
					e->ReportError();
					e->Delete();
				}

				// Stop the AVI
				pCancel->StopAVI();

				pCancel->ShowWindow(SW_HIDE);
				pCancel->ShutDown();

				::PostMessage(hParentWnd, WM_ENABLE, (WPARAM)TRUE, (LPARAM)0);
			}
			break;
		}	// switch on command
	}

   return hr;
}


////////////////////////////////////////////////////////////////////////
//
//  FUNCTION: CShellExt::GetCommandString(...)
//
//  PURPOSE: Retrieve various text strinsg associated with the context menu
//
//	Param			Type			Use
//	-----			----			---
//	idCmd			UINT			ID of the command
//	uFlags			UINT			which type of info are we requesting
//	reserved		UINT *			must be NULL
//	pszName			LPSTR			output buffer
//	cchMax			UINT			max chars to copy to pszName
//
////////////////////////////////////////////////////////////////////////

STDMETHODIMP CShellExt::GetCommandString(UINT idCmd,
                                         UINT uFlags,
                                         UINT FAR *reserved,
                                         LPSTR pszName,
                                         UINT cchMax)
{
   ODS("CShellExt::GetCommandString()\r\n");
	
	AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

	HINSTANCE hInst = AfxGetInstanceHandle();

	switch (uFlags) 
   {
	case GCS_HELPTEXT:		// fetch help text for display at the bottom of the 
							// explorer window
		switch (idCmd)
		{
			case 0:
            strncpy(pszName, "Encrypt the selected file(s)/directory(s)", cchMax);
				break;
			case 1:
            strncpy(pszName, "Decrypt the selected file(s)/directory(s)", cchMax);
				break;
         default:
            strncpy(pszName, SHELLEXNAME, cchMax);
				break;
		}
		break;

	case GCS_VALIDATE:
		break;

	case GCS_VERB:			// language-independent command name for the menu item 
		switch (idCmd)
		{
			case 0:
            strncpy(pszName, "Encrypt", cchMax);
				break;
			case 1:
            strncpy(pszName, "Decrypt", cchMax);
				break;
         default:
            strncpy(pszName, SHELLEXNAME, cchMax);
				break;
		}

		break;
	}
    return NOERROR;
}

///////////////////////////////////////////////////////////////////////////
//
//  FUNCTION: CShellExt::QueryContextMenu(HMENU, UINT, UINT, UINT, UINT)
//
//  PURPOSE: Called by the shell just before the context menu is displayed.
//           This is where you add your specific menu items.
//
//  PARAMETERS:
//    hMenu      - Handle to the context menu
//    indexMenu  - Index of where to begin inserting menu items
//    idCmdFirst - Lowest value for new menu ID's
//    idCmtLast  - Highest value for new menu ID's
//    uFlags     - Specifies the context of the menu event
//
//  RETURN VALUE:
//
//
//  COMMENTS:
//
///////////////////////////////////////////////////////////////////////////

STDMETHODIMP CShellExt::QueryContextMenu(HMENU hMenu,
                                         UINT indexMenu,
                                         UINT idCmdFirst,
                                         UINT idCmdLast,
                                         UINT uFlags)
{
   AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

   return CreateShellExtMenu(hMenu, 
                              indexMenu, 
                              idCmdFirst, 
                              idCmdLast, 
                              uFlags, 
                              (HBITMAP)m_menuBmp.GetSafeHandle());
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -