c ++ win32 console app使用windows api添加“选择文件”对话框

时间:2017-03-29 22:45:34

标签: c++ user-interface visual-studio-2017 windows-api-code-pack getopenfilename

我正在尝试向我的项目添加一个选择文件对话框,现在只能输入用户输入的文件名。

我做了一些搜索,似乎带有GetOpenFileName函数的windows API对我来说是最简单的方法。但是,当我从MSDN或其他网站复制并粘贴示例代码时,我遇到了一些构建错误。

我正在使用Visual Studio 2017.我使用的示例代码来自http://www.cplusplus.com/forum/windows/169960/

#include <iostream>

#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

int main()
{
  char filename[ MAX_PATH ];

  OPENFILENAME ofn;
    ZeroMemory( &filename, sizeof( filename ) );
    ZeroMemory( &ofn,      sizeof( ofn ) );
    ofn.lStructSize  = sizeof( ofn );
    ofn.hwndOwner    = NULL;  // If you have a window to center over, put its HANDLE here
    ofn.lpstrFilter  = "Text Files\0*.txt\0Any File\0*.*\0";
    ofn.lpstrFile    = filename;
    ofn.nMaxFile     = MAX_PATH;
    ofn.lpstrTitle   = "Select a File, yo!";
    ofn.Flags        = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;

  if (GetOpenFileNameA( &ofn ))
  {
    std::cout << "You chose the file \"" << filename << "\"\n";
  }
  else
  {
    // All this stuff below is to tell you exactly how you messed up above. 
    // Once you've got that fixed, you can often (not always!) reduce it to a 'user cancelled' assumption.
    switch (CommDlgExtendedError())
    {
      case CDERR_DIALOGFAILURE   : std::cout << "CDERR_DIALOGFAILURE\n";   break;
      case CDERR_FINDRESFAILURE  : std::cout << "CDERR_FINDRESFAILURE\n";  break;
      case CDERR_INITIALIZATION  : std::cout << "CDERR_INITIALIZATION\n";  break;
      case CDERR_LOADRESFAILURE  : std::cout << "CDERR_LOADRESFAILURE\n";  break;
      case CDERR_LOADSTRFAILURE  : std::cout << "CDERR_LOADSTRFAILURE\n";  break;
      case CDERR_LOCKRESFAILURE  : std::cout << "CDERR_LOCKRESFAILURE\n";  break;
      case CDERR_MEMALLOCFAILURE : std::cout << "CDERR_MEMALLOCFAILURE\n"; break;
      case CDERR_MEMLOCKFAILURE  : std::cout << "CDERR_MEMLOCKFAILURE\n";  break;
      case CDERR_NOHINSTANCE     : std::cout << "CDERR_NOHINSTANCE\n";     break;
      case CDERR_NOHOOK          : std::cout << "CDERR_NOHOOK\n";          break;
      case CDERR_NOTEMPLATE      : std::cout << "CDERR_NOTEMPLATE\n";      break;
      case CDERR_STRUCTSIZE      : std::cout << "CDERR_STRUCTSIZE\n";      break;
      case FNERR_BUFFERTOOSMALL  : std::cout << "FNERR_BUFFERTOOSMALL\n";  break;
      case FNERR_INVALIDFILENAME : std::cout << "FNERR_INVALIDFILENAME\n"; break;
      case FNERR_SUBCLASSFAILURE : std::cout << "FNERR_SUBCLASSFAILURE\n"; break;
      default                    : std::cout << "You cancelled.\n";
    }
  }
}

当我复制并粘贴到vs时,它会显示以下内容:

Severity    Code    Description Project File    Line    Suppression State
Error   C2440   '=': cannot convert from 'char [260]' to 'LPWSTR'   ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp    18  
Severity    Code    Description Project File    Line    Suppression State
Error   C2440   '=': cannot convert from 'const char [19]' to 'LPCWSTR' ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp    20  
Severity    Code    Description Project File    Line    Suppression State
Error   C2664   'BOOL GetOpenFileNameA(LPOPENFILENAMEA)': cannot convert argument 1 from 'OPENFILENAME *' to 'LPOPENFILENAMEA'  ConsoleApplication1 c:\users\xfan0\documents\visual studio 2017\projects\consoleapplication1\consoleapplication1\consoleapplication1.cpp    23  

Severity    Code    Description Project File    Line    Suppression State
Error (active)  E0167   argument of type "OPENFILENAME *" is incompatible with parameter of type "LPOPENFILENAMEA"  ConsoleApplication1 c:\Users\XFAN0\Documents\Visual Studio 2017\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp    23  

试图搜索但没找到我的运气:(

1 个答案:

答案 0 :(得分:1)

Microsoft通常提倡的方法是使用他们的“通用文本”宏,因此您的字符串文字将如下所示:

package demo;


import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestAnyURL_TestNG 
{

    WebDriver driver;    

    @BeforeTest     
    public void setup ()    
    {          
    System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
    ChromeOptions options = new ChromeOptions();
    options.addArguments("test-type");
    options.addArguments("start-maximized");
    options.addArguments("--js-flags=--expose-gc");  
    options.addArguments("--enable-precise-memory-info"); 
    options.addArguments("--disable-popup-blocking");
    options.addArguments("--disable-default-apps");
    options.addArguments("test-type=browser");
    options.addArguments("disable-infobars");
    driver = new ChromeDriver(options);               
    driver.manage().deleteAllCookies();          
    } 


    @Test(priority = 0)     
    public void Validlogin_IO () throws InterruptedException    
    {
    driver.navigate().to("http://google.com"); //ForSe test environment URL 
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    driver.findElement(By.xpath("//*[@id='email_address']")).sendKeys("tengku.forse@gmail.com"); //this is official email 
    driver.findElement(By.xpath("//*[@id='password']")).sendKeys("Pass12345"); //this is password 
    driver.findElement(By.xpath("//*[@id='login-form']/div[4]/button")).click(); //click on submit button to login  
    System.out.println("Login button pressed");     }       //This code is to add new case  

    @Test (priority = 1)    
    public void AddCase() throws InterruptedException
    {          
    WebElement element = driver.findElement(By.partialLinkText("Add Case")); //To find 'Add Case' button on dashboard
    Actions action = new Actions (driver);      action.moveToElement(element); //Move mouse and hover to 'Add Case' button 
    action.click().build().perform(); //Click on 'Add Case' button 
    driver.findElement(By.id("name")).sendKeys("Perak Murder Case -53311");//Provide Case Name 
    driver.findElement(By.id("fileupload")).sendKeys("C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1187.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1188.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\FisheyeImages\\IMG_1189.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\Fisheye Images\\IMG_1190.JPG");  //Upload files      
    driver.findElement(By.id("fileupload1")).sendKeys("C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\EvidenceImages\\_DSC0970.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSI>Images\\EvidenceImages\\_DSC0971.JPG"+"\n"+"C:\\Users\\sanchit.IGENEDC\\Desktop\\iCSIImages\\Evidence Images\\_DSC0972.JPG");
    Thread.sleep(6000);         //wait for files to load        
    driver.findElement(By.id("btnSubmit")).click();//click on submit button     
   }
}

这样,您可以构建窄字符或宽字符串(后者通过定义ofn.lpstrFilter = _T("Text Files\0*.txt\0Any File\0*.*\0"); ofn.lpstrTitle = _T("Select a File, yo!"); UNICODE)。对于窄字符构建,_UNICODE将映射为空,对于宽字符构建,_T将映射为L,因此您可以自动为正在构建的方式获取正确的字符串。< / p>

要使用此功能,请添加<tchar.h>

例如:

#include <iostream>
#include <tchar.h>

#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>

int main()
{
  char filename[ MAX_PATH ];

  OPENFILENAME ofn;
    ZeroMemory( &filename, sizeof( filename ) );
    ZeroMemory( &ofn,      sizeof( ofn ) );
    ofn.lStructSize  = sizeof( ofn );
    ofn.hwndOwner    = NULL;  // If you have a window to center over, put its HANDLE here
    ofn.lpstrFilter  = _T("Text Files\0*.txt\0Any File\0*.*\0");
    ofn.lpstrFile    = filename;
    ofn.nMaxFile     = MAX_PATH;
    ofn.lpstrTitle   = _T("Select a File, yo!");
    ofn.Flags        = OFN_DONTADDTORECENT | OFN_FILEMUSTEXIST;

  if (GetOpenFileName( &ofn ))
  {
    std::cout << "You chose the file \"" << filename << "\"\n";
  }
  else
  {
    // All this stuff below is to tell you exactly how you messed up above. 
    // Once you've got that fixed, you can often (not always!) reduce it to a 'user cancelled' assumption.
    switch (CommDlgExtendedError())
    {
      case CDERR_DIALOGFAILURE   : std::cout << "CDERR_DIALOGFAILURE\n";   break;
      case CDERR_FINDRESFAILURE  : std::cout << "CDERR_FINDRESFAILURE\n";  break;
      case CDERR_INITIALIZATION  : std::cout << "CDERR_INITIALIZATION\n";  break;
      case CDERR_LOADRESFAILURE  : std::cout << "CDERR_LOADRESFAILURE\n";  break;
      case CDERR_LOADSTRFAILURE  : std::cout << "CDERR_LOADSTRFAILURE\n";  break;
      case CDERR_LOCKRESFAILURE  : std::cout << "CDERR_LOCKRESFAILURE\n";  break;
      case CDERR_MEMALLOCFAILURE : std::cout << "CDERR_MEMALLOCFAILURE\n"; break;
      case CDERR_MEMLOCKFAILURE  : std::cout << "CDERR_MEMLOCKFAILURE\n";  break;
      case CDERR_NOHINSTANCE     : std::cout << "CDERR_NOHINSTANCE\n";     break;
      case CDERR_NOHOOK          : std::cout << "CDERR_NOHOOK\n";          break;
      case CDERR_NOTEMPLATE      : std::cout << "CDERR_NOTEMPLATE\n";      break;
      case CDERR_STRUCTSIZE      : std::cout << "CDERR_STRUCTSIZE\n";      break;
      case FNERR_BUFFERTOOSMALL  : std::cout << "FNERR_BUFFERTOOSMALL\n";  break;
      case FNERR_INVALIDFILENAME : std::cout << "FNERR_INVALIDFILENAME\n"; break;
      case FNERR_SUBCLASSFAILURE : std::cout << "FNERR_SUBCLASSFAILURE\n"; break;
      default                    : std::cout << "You cancelled.\n";
    }
  }
}

要获取“保存”文件名,只需将GetOpenFilename更改为GetSaveFilename即可。虽然你可能会在OPENFILENAME中传递的标志有一些差异 - 例如,当你打开一个文件时传递OFN_FILEMUSTEXIST是很常见的,但是你几乎不想要这样做。重新保存文件。