VC++问题集9

81.如何浏览文件
 看如下示例代码:
 CString ReturnPach;
 TCHAR szPath[_MAX_PATH];
 BROWSEINFO bi;
 bi.hwndOwner=NULL;
 bi.pidlRoot=NULL;
 bi.lpszTitle=_T("请选择一个文件夹");
 bi.pszDisplayName=szPath;
 bi.ulFlags=BIF_RETURNONLYFSDIRS;
 bi.lpfn=NULL;
 bi.lParam=NULL;
 LPITEMIDLIST pItemIDList=SHBrowseForFolder(&bi);
 if(pItemIDList)//如果选择了文件则找到那选择的文件的路径。
 {
  if(SHGetPathFromIDList(pItemIDList,szPath))
   ReturnPach=szPath; 
 }
 else
  ReturnPach="";
 m_path.SetWindowText(ReturnPach);
 注:SHBrowseForFolder函数如果用户点击了取消则返回NULL;
82.如何实现移动文件夹
 MoveFile方法用于实现不同文件夹下移动文件的操作,相当于系统中的剪切命令。

83.如何更改文件夹图标
 文件夹图标的修改需要在目标文件夹下新建一个Desktop.ini文件,并在文件中添加键值。
 具体过程为:在该ini文件的[v.ShellClassInfo]节下,添加IconFile=图标 1.ico和
 IconIndex=0.IconFile是指定图标文件,最好和ini文件在同一个文件下,如果不在同一个文件
 下,应该使用图标资源的全路径;IconIndex是指定图标的索引,一般为0.

84.如何获取文件夹的图标信息。
 得到文件的路径名,然后用::SHGetFileInfo(path,0,&shfile,sizeof(shfile),AHGIF_ICON);
 SHFILEINFO shfile;
 
85.判断一个可执行文件或DLL中是否有图标存在,并将其提取出来可用ExtractIcon方法。

86.重命名文件可以使用stdio.h文件下的rename函数。

87.如何设置文件属性?
 我们可以通过CFile类的GetStatus方法和SetStatus方法来实现。具体实现过程请参考如下代码:
 CFileStatus status;
 BYTE m_newattri;
 if(m_ar.GetCheck())
 {
 m_newattri=0x20;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 }
 if(m_dir.GetCheck())
 {
 m_newattri=0x10;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 } 
 if(m_hide.GetCheck())
 {
 m_newattri=0x02;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 }
 if(m_normal.GetCheck())
 {
 m_newattri=0x00;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 }
 if(m_readonly.GetCheck())
 {
 m_newattri=0x00;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 m_newattri=0x01;
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 }
 if(m_system.GetCheck())
 {
 m_newattri=0x04;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 } 
 if(m_vol.GetCheck())
 {
 m_newattri=0x08;
 CFile::GetStatus(pathname,status);
 status.m_attribute=m_newattri;
 CFile::SetStatus(pathname,status);
 }
88.修改目录的名称:我们可以使用MoveFile方法。MoveFile方法主要用来移动文件或目录,通过它
 可以达到修改目录名称的目的.

89.读取文本文件也可以使用CStdioFile类的ReadString方法实现.

90.如何实现文件分割?
 要想实现文件分割,其实很简单,我们只要用CFile中的Read方法就能把一个文件分割成若干个
 文件。把分割后的文件合在一起并成原来的文件只需用Write方法就行。

91.如何利用WinRar压缩和解压文件?
 我们可以通过ShellExecute函数调用WinRar.exe实现文件的压缩和解压。
 WinRar.exe的语法如下:
 解压:
 WINRAR X[-switches][Files][@File lists][destionation folder]
 压缩:
 WINRAR A[-switches][Files][@File lists]
 如下示例代码:
 解压:
 void OnUnZip()
 {
  CString source,path,temp;
  GetDlgItem(IDC_EDSOURCE)->GetWindowText(source);
  int pos=source.Find(".");
  path=source.Left(pos);
  temp.Format("X %s %s",source,path);
  ::CreateDirectory(path,NULL);
  ::ShellExecute(NULL,"open","WinRar.exe",temp,NULL,SW_SHOW);
 }
 压缩:
 void OnZip()
 {
  CString des,temp,path,rarpath;
  GetDlgItem(IDC_EDDES)->GetWindowText(des);
  path.Format("%s//*.*",des);
  rarpath.Format("%s//mingrisoft.rar",des);
  temp.Format("a %s %s",rarpath,path);
  ::ShellExecute(NULL,"open","WinRar.exe",temp,NULL,SW_SHOW);
 }

92.如何修改Windows XP的注册表,使得机子启动时弹出提示框?
 例如我们可以在HKEY_LOCAL_MACHINE/Software/Microsoft/WindowsNT/CurrentVersion
 /Winlogon 下面新建一个名为"Legalnoticecaption"的字符串值,将它的数据设置成提示
 信息的标题,如"警告"或"用户注意事项"等。在"Winlogon"次级主键下再建一个名为
 "LegalNoticeText"的字符串值,输入提示信息,如"欢迎进入Windows"等。
 这样,进入WindowsXP前就会发出警告信息,弹出警告对话框信息.
 在VC++用程序实现如下:
 void OnAdd()
 {
  CString strtitle,strbody;
  GetDlgItem(IDC_EDTITLE)->GetWindowText(strtitle);
  GetDlgItem(IDC_EDBODY)->GetWindowText(strbody);
  HKEY sub;
  CString skey="Software//Microsoft//Windows NT//CurrentVersion//Winlogon";
  ::RegCreateKey(HKEY_LOCAL_MACHINE,skey,&sub);
  RegSetValueEx(sub,"legalnoticecaption",NULL,REG_SZ,
    (BYTE*)strtitle.GetBuffer(0),strtitle.GetLength()); 
  RegSetValueEx(sub,"LegalNoticeText",NULL,REG_SZ,
    (BYTE*)strbody.GetBuffer(0),strbody.GetLength()); 
  RegCloseKey(sub);
 }
 删除键值:
 void OnMove()
 {
  HKEY sub;
  CString skey="Software//Microsoft//Windows NT//CurrentVersion//Winlogon";
  ::RegCreateKey(HKEY_LOCAL_MACHINE,skey,&sub);
  ::RegDeleteValue(sub,"legalnoticecaption");
  ::RegDeleteValue(sub,"LegalNoticeText");
  RegCloseKey(sub);
 }
93.如何用程序实现:关闭重启注销计算机?
 重新启动计算机,关闭计算机和注销计算机只需要ExitWindowsEx函数即可实现,
 但在Windows 2000 系统下应用程序获得相关权限时才可能实现,这就需要用OpenProcessToken
 函数、LookupPrivilegeValue函数和AdjustTokenPrivileges函数的组合使用.
 BOOL OpenProcessToken(//获得应用程序权限的令牌
    HANDLE ProcessHandle, // handle to process
          //获取令牌的应用程序句柄
    DWORD DesiredAccess,  // desired access to process
          //访问令牌的请求类型
    PHANDLE TokenHandle   // pointer to handle of open access token
          //令牌句柄
  );
 BOOL LookupPrivilegeValue(//获得权限的唯一标识值
    LPCTSTR lpSystemName, // address of string specifying the system
          //权限所在的系统名称
    LPCTSTR lpName,       // address of string specifying the privilege
          //权限的名称
   PLUID lpLuid          // address of locally unique identifier
          //权限的唯一标识值
  );
 BOOL AdjustTokenPrivileges(//设置令牌的权限
   HANDLE TokenHandle,  // handle to token that contains privileges
         //令牌句柄
   BOOL DisableAllPrivileges,// flag for disabling all privileges
                                //打开或关闭令牌权限
    PTOKEN_PRIVILEGES NewState,// pointer to new privilege information
                             //新的TOKEN_PRIVILEGES结构对象,TOKEN_PRIVILEGES
        //结构包含着一些权限信息及权限的属性
    DWORD BufferLength,  // size, in bytes, of the PreviousState buffer
         //上一个TOKEN_PRIVILEGES结构对象的缓存大小
    PTOKEN_PRIVILEGES PreviousState,// receives original state of changed privileges
                            //上一个TOKEN_PRIVILEGES结构对象
    PDWORD ReturnLength  // receives required size of the PreviousState buffer
                             //返回上一个TOKEN_PRIVILEGES结构对象所要求的缓存大小。
 如下为示例代码:(设置关机权限)
 OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken);
 LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid);
 tp.PrivilegeCount =1;
 tp.Privileges [0].Luid =luid;
 tp.Privileges [0].Attributes =SE_PRIVILEGE_ENABLED;
 AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),NULL, NULL);
);

94.如何修改注册表让程序开机自动运行?
 在HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run 下新建一个字符串,
 值要为自动运行程序名,将它的参数设置成程序所在目录,即可将该程序设置为自动执行.
 例如:
 建一个Thunder 其值为"C:/Program Files/Thunder Network/Thunder/Thunder.exe" /s
 让程序自动运行有两种方法,一种是把可执行文件放在开始--程序--启动的文件夹下;
      另一种如上。

95.如何判断驱动器属性?
 我们可以通过GetDriveType函数来获得驱动器的类型。使用方法请查阅MSDN。

96.如何获取磁盘序列号
 计算机的磁盘或硬盘格式化后都有对应的磁盘序列号。我们可以通过GetVolumeInformation函数
 来获取磁盘驱动器序列号,该函数是用来 获得文件系统中根目录磁盘卷标信息的。
 其语法如下:
 BOOL GetVolumeInformation(
    LPCTSTR lpRootPathName,        // address of root directory of the
                                   // file system
      //根目录名称
   LPTSTR lpVolumeNameBuffer,     // address of name of the volume
            //存放卷标名称的缓存
    DWORD nVolumeNameSize,         // length of lpVolumeNameBuffer
      //卷标名称大小
    LPDWORD lpVolumeSerialNumber,  // address of volume serial number
      //卷标的序列号
    LPDWORD lpMaximumComponentLength,
                                  // address of system's maximum
                                   // filename length
      //最大文件名长度
    LPDWORD lpFileSystemFlags,     // address of file system flags
      //文件系统标志
    LPTSTR lpFileSystemNameBuffer, // address of name of file system
      //存放文件系统名称的缓存
    DWORD nFileSystemNameSize      // length of lpFileSystemNameBuffer
      //存放文件系统名称的大小
 );
 示例代码:
 LPTSTR namebuf=new char[12];
 DWORD namesize=12;
 DWORD serialnumber;
 DWORD maxlen;
 DWORD fileflag;
 LPTSTR sysnamebuf=new char[10];
 DWORD sysnamesize=10;
 ::GetVolumeInformation("c://",namebuf,namesize,&serialnumber,&maxlen,&fileflag,
   sysnamebuf,sysnamesize);

97. 如何取消磁盘共享?
 取消默认共享需要在控制台使用net命令,例如要取消C盘的默认共享,需要使用net share
 c:/del 命令。我们可以通过WinExec函数来执行关闭磁盘默认共享的net命令,该函数是在
 程序中执行其他可执行文件,语法如下:
 UINT WinExec(
    LPCSTR lpCmdLine,  // address of command line
       //命令行字符串,包括其他可执行文件所调用的参数
    UINT uCmdShow      // window style for new application
       //执行其他可执行文件时窗体的显示设置
  );
 如下示例代码:
 CString strcmd="net.exe share F:/del";
 ::WinExec(strcmd,SW_HIDE); 
98.磁盘是计算机存储数据的一种主要介质,主要分为两种:软盘(Floppy Disk)和硬盘(Hard Disk)。
 硬盘在使用之前先进行低级格式化(也称物理格式化),然后进行分区,最后进行高级格式
 化(也称逻辑格式化),这样才能存储数据。软盘不需要进行前两个步骤,直接进行高级格
 式化就能够使用了。通常硬盘在出厂前已经进行了低级格式化,使用前直接分区和高级格
 式化即可。高级格式化操作能将磁盘中的数据清空,并且能够恢复一些逻辑性的磁盘错误,
 因此常常被使用。
 在程序中我们可以调用FormatDriver函数来显示格式化磁盘的对话框,该函数是Shell32.dll
 文件中的函数。
 语法如下:
 FormatDriver(HWND hwnd,UINT drive,UINT fmtID,UINT options)
 参数说明:
 hwnd: 应用程序窗体句柄
 drive:磁盘驱动器序号.
 fmtID:格式化ID
 options:格式化选项
 如下示例代码:
 typedef DWORD (WINAPI *MyFunc)(HWND hwnd,
 UINT drive,UINT fmtID,UINT options);
 HMODULE hModule=::LoadLibrary("shell32.dll");
 if(hModule)
 {
  MyFunc FormatDriver= (MyFunc) GetProcAddress(hModule, "SHFormatDrive");
  if(FormatDriver)
   FormatDriver(this->GetSafeHwnd(),'F'-'A',0xFFFF,0);
 }

99.如何隐藏、显示"开始"按钮?
 我们可以通过使用FindWindow函数和FindWindowEx函数查找具体窗体句柄,通过ShowWindow函数
 达到隐藏和显示窗体的目的。"开始"按钮在任务栏窗体上,任务栏的窗体类名称是
 "Shell_TrayWnd".
 如下示例代码:
 隐藏"开始按钮"
 void OnHide()
 {
  HWND parent=::FindWindow("Shell_TrayWnd","");
  HWND startmenu=::FindWindowEx(parent,0,"Button",NULL);
  if(startmenu!=NULL)
  {
   ::ShowWindow(startmenu,SW_HIDE);
  }
 }
 显示开始按钮:
 void OnShow()
 {
  HWND parent=::FindWindow("Shell_TrayWnd","");
  HWND startmenu=::FindWindowEx(parent,0,"Button",NULL);
  if(startmenu!=NULL)
  {
   ::ShowWindow(startmenu,SW_SHOW);
  }
 }

100.如何隐藏、显示桌面文件?
 这方法和99问一样。桌面窗体名称是Program Manager,窗体类名称是Progman。
 示例代码如下:
 隐藏桌面:
 void OnHide()
 {
  /*通过注册表来隐藏桌面
  HKEY sub;
  DWORD data=1;
  CString skey="Software//Microsoft//Windows//CurrentVersion
    //Policies//Explorer";
  ::RegCreateKey(HKEY_CURRENT_USER,skey,&sub);
  RegSetValueEx(sub,"nodesktop",NULL,REG_DWORD,(BYTE*)&data,sizeof(DWORD)); 
  RegCloseKey(sub);
  */
  //HWND desktop=::FindWindow("Progman",NULL);
  HWND desktop=::FindWindow(NULL,"Program Manager");
  if(desktop!=NULL)
  {
   ::ShowWindow(desktop,SW_HIDE);
  } 
 }
 显示桌面
 void OnShow()
 {
  /*
  HKEY sub;
  DWORD data=0;
  CString skey="Software//Microsoft//Windows//CurrentVersion//Policies//Explorer";
  ::RegCreateKey(HKEY_CURRENT_USER,skey,&sub);
  RegSetValueEx(sub,"nodesktop",NULL,REG_DWORD,(BYTE*)&data,sizeof(DWORD)); 
  RegCloseKey(sub);
  */
  HWND desktop=::FindWindow("Progman",NULL);
  if(desktop!=NULL)
  {
   ::ShowWindow(desktop,SW_SHOW);
  }
 }

你可能感兴趣的:(shell,null,Path,vc++,token,磁盘)