天天看点

在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

继续阅读