QGIS3.4x的二次开发(二)

最近开始研究 QGIS 3.4.x,QGIS 3.4.x 改为 一个console做启动,读取环境配置文件,另外把qgis应用做成一个dll,由console启动。这样的好处就是QGIS可以做成绿色软件,降低对环境变量配置要求。

好了,不多说,直接上代码。

一、console代码,直接改自qgis的代码

#include <windows.h>
#include <io.h>

#include <sstream>
#include <iostream>
#include <fstream>
#include <list>
#include <memory>

void showError( std::string message, std::string title )
{
  std::string newmessage = "Oops, looks like an error loading QGIS \n\n Details: \n\n" + message;
  MessageBox(
    NULL,
    newmessage.c_str(),
    title.c_str(),
    MB_ICONERROR | MB_OK
  );
  std::cerr << message << std::endl;
}

std::string moduleExeBaseName( void )
{
  DWORD l = MAX_PATH;
  std::unique_ptr<char> filepath;
  for ( ;; )
  {
    filepath.reset( new char[l] );
    if ( GetModuleFileName( nullptr, filepath.get(), l ) < l )
      break;

    l += MAX_PATH;
  }

  std::string basename( filepath.get() );
  basename.resize( basename.length() - 4 );
  return basename;
}


int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
  std::string basename( moduleExeBaseName() );

  try
  {
    std::ifstream file;
    file.open( basename + ".env" );

    std::string var;
    while ( std::getline( file, var ) )
    {
      if ( _putenv( var.c_str() ) < 0 )
      {
        std::string message = "Could not set environment variable:" + var;
        showError( message, "Error loading QGIS" );
        return EXIT_FAILURE;
      }
    }
  }
  catch ( std::ifstream::failure e )
  {
    std::string message = "Could not read environment file " + basename + ".env" + " [" + e.what() + "]";
    showError( message, "Error loading QGIS" );
    return EXIT_FAILURE;
  }

  HINSTANCE hGetProcIDDLL = LoadLibrary( "MyPowerApp.dll" );

  if ( !hGetProcIDDLL )
  {
    DWORD error = GetLastError();
    LPTSTR errorText = NULL;

    FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      error,
      MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
      ( LPTSTR )&errorText,
      0,
      NULL );

    std::string message = "Could not load qgis_app.dll \n Windows Error: " + std::string( errorText )
                          + "\n Help: \n\n Check " + basename + ".env for correct environment paths";
    showError( message, "Error loading QGIS" );

    LocalFree( errorText );
    errorText = NULL;
    return EXIT_FAILURE;
  }

  int ( *realmain )( int, char *[] ) = ( int ( * )( int, char *[] ) ) GetProcAddress( hGetProcIDDLL, "main" );
  if ( !realmain )
  {
    showError( "Could not locate main function in qgis_app.dll", "Error loading QGIS" );
    return EXIT_FAILURE;
  }

  return realmain( __argc, __argv );
}

 

二、dll代码

#include "mypowerapp_global.h"
#include "QgsApplication.h"
#include "QPowerMain.h"

int MYPOWERAPP_EXPORT main(int argc, char *argv[])
{
    QgsApplication a(argc, argv, true);
    QgsApplication::initQgis();    //初始化QGIS应用

    QPowerMain w;    //创建一个窗体,类似于Qt
    w.show();

    return a.exec();
}
 

记得要设置main为MYPOWERAPP_EXPORT。其他的跟往常一样。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章