天天看點

在notepad++插件開發中使用QT

在notepad++裡面使用qt,首先要做得就是建立qt工程,然後類型是動态連結庫,然後将notepad++的模闆檔案拷貝進去,在裡面就可以用用qt書寫代碼了.編譯以後的dll拷貝到notepad++的plugins檔案夾内,然後将qt依賴拷貝到notepad++同級目錄,就可以正确加載了.

       比較麻煩的是怎麼把qt窗體塞到notepad++裡面.這裡我采用的方式是先建立一個它原來支援的窗體,然後根據句柄設定qt窗體的父窗體,進而間接地塞了進去.代碼如下:

class MainView : public QWidget
{
       Q_OBJECT
public:
       MainView(QWidget *parent = 0);
       ~MainView();
}
           

這個是我的qt窗體類,它的實作各位就各自發揮了

#ifndef GOTILINE_DLG_H
#define GOTILINE_DLG_H

#include "DockingDlgInterface.h"
#include "resource.h"
#include "QDialog"
#include "mainview.h"


class DemoDlg : public DockingDlgInterface
{
public :
	DemoDlg() : DockingDlgInterface(IDD_PLUGINGOLINE_DEMO), dlg(NULL){};
	~DemoDlg();
    virtual void display(bool toShow = true) const {
        DockingDlgInterface::display(toShow);
    };

	void setParent(HWND parent2set){
		_hParent = parent2set;
	};

	void create(tTbData * data, bool isRTL = false);
	MainView* dlg;
protected :
	virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
};

#endif //GOTILINE_DLG_H
           
#include "QtDialogParent.h"
#include "PluginDefinition.h"
extern NppData g_nppData;
#define MINIMUM_WINDOWS_X 350    
#define MINIMUM_WINDOWS_Y 200  

BOOL CALLBACK DemoDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_COMMAND:
	{
		switch (wParam)
		{
		case IDOK:
		{
			return TRUE;
		}
		}
		return FALSE;
	}
	case WM_GETMINMAXINFO:
	{
		((MINMAXINFO *)lParam)->ptMinTrackSize.x = MINIMUM_WINDOWS_X;
		((MINMAXINFO *)lParam)->ptMinTrackSize.y = MINIMUM_WINDOWS_Y;
		return TRUE;
	}
	case WM_SIZE:
	{
		if (dlg)
		{
			int x = ((int)(short)LOWORD(lParam));
			int y = ((int)(short)HIWORD(lParam));
			dlg->setGeometry(0, 0, x, y);
		}
		return TRUE;
	}
	break;
	default:
		return DockingDlgInterface::run_dlgProc(message, wParam, lParam);
	}
}

void DemoDlg::create(tTbData * data, bool isRTL /*= false*/)
{
	DockingDlgInterface::create(data, isRTL);
	int arg = 1;
	dlg = new MainView;
	::SetParent((HWND)dlg->winId(), _hSelf);
	dlg->show();
};

DemoDlg::~DemoDlg()
{
	if (dlg!=NULL)
	{
		delete dlg;
	}
}
           

這個是給qt窗體準備的父窗體.

然後在全局變量裡面聲明一個

DemoDlg g_dlg;
           

在子產品加載的時候進行初始化

void pluginInit(HANDLE hModule)
{
       …
       g_dlg.init((HINSTANCE)hModule, NULL);
       …
}
           

然後QT的窗體也是全局的

MainView *g_view = NULL;
           

然後顯示窗體的指令這麼寫

void showDlg()
{
       g_dlg.setParent(g_nppData._nppHandle);
       tTbData data = { 0 };
       if (!g_dlg.isCreated())
       {
              g_dlg.create(&data);
              g_view = g_dlg.dlg;
              data.hIconTab =(HICON)::LoadImage((HINSTANCE)g_module, MAKEINTRESOURCE(IDI_ICO), IMAGE_ICON,16, 16, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);
              data.pszName  = TEXT("Lua插件");
              data.uMask = DWS_DF_CONT_RIGHT;
              data.pszModuleName =TEXT("luatool.dll");
              data.dlgID =IDD_PLUGINGOLINE_DEMO;
              ::SendMessage(g_nppData._nppHandle,NPPM_DMMREGASDCKDLG, 0, (LPARAM)&data);
       }
       g_dlg.display();
}
           

這樣就可以把qt窗體塞進notepad++裡面了,這裡需要注意的地方是    

virtual BOOL CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam);
           

這個函數,窗體發生改變的時候會進入這個回調函數,比如窗體大小發生了改變,那麼我們判斷是WM_SIZE信号,那麼我們拿到最新的大小設定給qt窗體就可以了.

然後 擷取qt窗體的句柄使用的函數是winId()這個函數,然後強制轉換為HWND即可.

最後,也是最重要的是 qt的窗體是依賴于QApplication的,否則無法正常工作,是以需要定義一個全局的

QApplication* app = NULL;

dll加載的時候需要new出一個來,代碼如下

QApplication* app = NULL;

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  reasonForCall, 
                       LPVOID lpReserved )
{
    switch (reasonForCall)
    {
	case DLL_PROCESS_ATTACH:
	{
		int arg = 1;
		char* argv = new char[1];
		argv[0] = '1';
		app = new QApplication(arg, &argv);
		g_module = hModule;
		pluginInit(hModule);
	}
       
        break;

	  case DLL_PROCESS_DETACH:
	  {
		  delete g_AutoManager;
		  commandMenuCleanUp();
		  pluginCleanUp();
		  delete app;
	  }
		
        break;
      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
	
        break;
    }

    return TRUE;
}
           

最後結果如下

在notepad++插件開發中使用QT
在notepad++插件開發中使用QT

繼續閱讀