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。其他的跟往常一樣。

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