通过nsis和duilib实现自定义安装界面
来源:互联网 发布:程序员社招招聘条件 编辑:程序博客网 时间:2024/05/18 23:15
nsis用于实现安装逻辑,duilib用于实现UI界面
通过nsis调用duilib生成的dll库来实现。现截取部分duilib代码用于展示如何使用duilib编写代码。
cpp文件如下:
#include <windows.h>#include <commctrl.h>#include <Shlobj.h>#include "plugin-common.h"#include "DlgMain.h"#pragma comment(lib,"Shell32.lib")HINSTANCE g_hInstance;HWND g_hwndParent;extra_parameters *g_pluginParms = NULL;CDlgMain *g_pMainDlg = NULL;std::map<HWND, WNDPROC> g_windowInfoMap;CDuiString g_progressCtrlName = _T("");CDuiString g_tabLayoutCtrlName = _T("");bool g_bMSGLoopFlag = true;#define NSMETHOD_INIT(parent) {\ g_pluginParms = extra; \ g_hwndParent = parent; \ EXDLL_INIT(); }BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved){ g_hInstance = (HINSTANCE)hInst; if (ul_reason_for_call == DLL_PROCESS_ATTACH) { //do what you want at init time. } if (ul_reason_for_call == DLL_THREAD_DETACH || ul_reason_for_call == DLL_PROCESS_DETACH) { //clean up code. } return TRUE;}// NSIS插件导出函数,NSIS规定函数声明格式如下:extern "C" __declspec(dllexport) void __cdecl/** 在nsis脚本中调用方法myPlugin::myFunction /NOUNLOAD $2* /NOUNLOAD 表示调用完此方法后不卸载这个dll,用于保存dll的数据* hwndParent:安装窗口的句柄* stacktop:nsis传入的参数堆栈, 通过popint/popstring 可以取出来* extra:插件里面调用script的函数就需要用到这个*/add(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { // == 添加自己代码 int i = popint(); int j = popint(); int k = i + j; pushint(k); // == }}//窗口大小extern "C" __declspec(dllexport) void __cdeclGetDialogSize(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { HWND hwnd = (HWND)popint(); RECT rect; ::GetWindowRect(hwnd, &rect); pushint(rect.bottom - rect.top); pushint(rect.right - rect.left); }}//窗口风格extern "C" __declspec(dllexport) void __cdeclGetDialogStyle(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { HWND hwnd = (HWND)popint(); int style = (int)::GetWindowLongA(hwnd, GWL_STYLE); pushint(style); }}extern "C" __declspec(dllexport) void __cdeclGetSetupPath(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[512] = { 0 }; ::GetModuleFileName(NULL, buf, 512); pushstring(buf); }}extern "C" __declspec(dllexport) void __cdeclTrace(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[1024] = { 0 }; popstring(buf); DUI__Trace(_T("NSISHelper Trace:%s"), buf); }}extern "C" __declspec(dllexport) void __cdeclGetCtrlPos(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { HWND hwnd = (HWND)popint(); RECT rect; GetClientRect(hwnd, &rect); DUI__Trace(_T("%d %d %d %d %d"), hwnd, rect.left, rect.top, rect.right, rect.bottom); POINT lt = { rect.left, rect.top }; POINT rb = { rect.right, rect.bottom }; ::ClientToScreen(hwndParent, <); ::ClientToScreen(hwndParent, &rb); pushint(rb.y); pushint(rb.x); pushint(lt.y); pushint(lt.x); }} //=========================================== DUILIB =============================================//许可协议界面NSISAPI FindControl(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ char controlName[MAX_PATH]; ZeroMemory(controlName, MAX_PATH); popstring(controlName); CControlUI *pControl = static_cast<CControlUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl(controlName)); if (pControl == NULL) pushint(-1); pushint(0);}//绑定控件NSISAPI OnControlBindNSISScript(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ char controlName[MAX_PATH]; ZeroMemory(controlName, MAX_PATH); popstring(controlName); int callbackID = popint(); g_pMainDlg->SaveToControlCallbackMap(controlName, callbackID);//放入所有控件}NSISAPI ExitDUISetup(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ ExitProcess(0);}static UINT_PTR PluginCallback(enum NSPIM msg){ return 0;}//初始化界面--欢迎界面NSISAPI InitDUISetup(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); extra->RegisterPluginCallback(g_hInstance, PluginCallback); { CPaintManagerUI::SetInstance(g_hInstance); char buf[512] = { 0 }; ::GetModuleFileName(NULL, buf, 512); int len = strlen(buf); --len; while (len >= 0) { if (buf[len] == '\\') break; buf[len] = '\0'; --len; } sprintf_s(buf, "%sskin", buf); //CPaintManagerUI::SetResourcePath(buf); g_pMainDlg = new CDlgMain(); g_pMainDlg->Create(NULL, _T("标题名字"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 588, 384); g_pMainDlg->CenterWindow(); g_pMainDlg->ShowWindow(FALSE); pushint(int(g_pMainDlg->GetHWND())); }}//显示页面NSISAPI ShowPage(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { g_pMainDlg->ShowWindow(true); //CPaintManagerUI::MessageLoop(); MSG msg = { 0 }; while (::GetMessage(&msg, NULL, 0, 0) && g_bMSGLoopFlag) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } }}//设置编辑框内容NSISAPI SetEdit(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[512] = { 0 }; popstring(buf); CEditUI *pEdit = static_cast<CEditUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl("btEdit")); if (pEdit) pEdit->SetText(buf); }}//checkBox选型NSISAPI GetCheckboxStatus(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char pszName[512] = { 0 }; popstring(pszName);//从nsis获取控件 CCheckBoxUI *pChbAgree = static_cast<CCheckBoxUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl(pszName)); if (!pChbAgree) { pushint(-1); return; } DUI__Trace("%s status:%d", pszName, pChbAgree->GetCheck() ? 1 : 0); pushint(pChbAgree->GetCheck() ? 1 : 0);//输出给nsis。 }}//设置进度NSISAPI SetSliderRange(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[512] = { 0 }; //从nsis接收多个参数 popstring(buf); int iMin = popint(); int iMax = popint(); CProgressUI *pProgress = static_cast<CProgressUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl(buf)); if (pProgress == NULL) return; //设置进度 pProgress->SetMaxValue(iMax); pProgress->SetMinValue(iMin); }}//设置进度值NSISAPI SetSliderValue(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[512] = { 0 }; popstring(buf); int iValue = popint(); CProgressUI *pProgress = static_cast<CProgressUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl(buf)); if (pProgress) pProgress->SetValue(iValue); }}//文件路径NSISAPI SetDirValue(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { char buf[512] = { 0 }; popstring(buf); CEditUI *pEdit = static_cast<CEditUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl("editDir")); if (pEdit) pEdit->SetText(buf); }}NSISAPI GetDirValue(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { CDuiString strFolderPath; CEditUI *pEdit = static_cast<CEditUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl("editDir")); if (pEdit) strFolderPath = pEdit->GetText(); pushstring((char*)strFolderPath.GetData()); }}//选择安装路径--点击更改弹出文件路径选择对话框NSISAPI SelectInstallDir(HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { //BROWSEINFO SHGetPathFromIDList 弹出文件夹选择框 BROWSEINFO bi; memset(&bi, 0, sizeof(BROWSEINFO)); bi.hwndOwner = g_pMainDlg->GetHWND(); bi.lpszTitle = "选择安装路径"; bi.ulFlags = 0x0040; char szFolderPath[MAX_PATH] = { 0 }; LPITEMIDLIST idl = SHBrowseForFolder(&bi); if (idl == NULL) { pushstring(szFolderPath); return; } SHGetPathFromIDList(idl, szFolderPath); CEditUI *pEdit = static_cast<CEditUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl("editDir")); if (pEdit) pEdit->SetText(szFolderPath); pushstring(szFolderPath); }}//更新NSISAPI StartInstall ( HWND hwndParent, int string_size, char *variables, stack_t **stacktop, extra_parameters *extra){ NSMETHOD_INIT(hwndParent); { g_bMSGLoopFlag = false; }}BOOL CALLBACK PluginNewWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ BOOL res = 0; std::map<HWND, WNDPROC>::iterator iter = g_windowInfoMap.find( hwnd ); if( iter != g_windowInfoMap.end() ) { if (message == WM_NCCREATE || message == WM_CREATE || message == WM_PAINT || message== WM_NCPAINT) { ShowWindow( hwnd, SW_HIDE ); } else if( message == LVM_SETITEMTEXT ) { ; } else if( message == PBM_SETPOS ) { CProgressUI *pProgress = static_cast<CProgressUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl( g_progressCtrlName )); if( pProgress == NULL ) return 0; pProgress->SetMaxValue( 30000 ); pProgress->SetValue( (int)wParam); if( pProgress->GetValue() == 30000 ) { CTabLayoutUI *pTab = static_cast<CTabLayoutUI *>(g_pMainDlg->GetPaintManagerUI()->FindControl( g_tabLayoutCtrlName )); if( pTab == NULL ) return -1; int currentIndex = pTab->GetCurSel(); DUI__Trace("tabName:%s index:%d",g_tabLayoutCtrlName,currentIndex); pTab->SelectItem(2); } } else { res = CallWindowProc( iter->second, hwnd, message, wParam, lParam); } } return res;}
如下代码用于控制控件的响应文件:
#include "DlgMain.h"CDlgMain::CDlgMain(){}CDlgMain::~CDlgMain(){}void CDlgMain::Notify( TNotifyUI& msg ){ std::map<CDuiString, int >::iterator iter = m_controlCallbackMap.find( msg.pSender->GetName() ); if( _tcsicmp( msg.sType, _T("click") ) == 0 ){ if( iter != m_controlCallbackMap.end() ) g_pluginParms->ExecuteCodeSegment( iter->second - 1, 0 ); } else if( _tcsicmp( msg.sType, _T("textchanged") ) == 0 ){ if( iter != m_controlCallbackMap.end() ) g_pluginParms->ExecuteCodeSegment( iter->second - 1, 0 ); } else { WindowImplBase::Notify(msg); }}LRESULT CDlgMain::HandleCustomMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ){ return 0;}void CDlgMain::InitWindow(){ CRichEditUI * pRichEdit = static_cast<CRichEditUI*>(m_PaintManager.FindControl(_T("editLicense"))); if(pRichEdit) { HRSRC hRsrc = FindResourceA(CPaintManagerUI::GetInstance(), MAKEINTRESOURCEA(IDR_TEXT_LICENSE), "TEXT"); if(!hRsrc) return; DWORD dwSize = SizeofResource(CPaintManagerUI::GetInstance(), hRsrc); if(dwSize==0) return; HGLOBAL hGlobal = LoadResource(CPaintManagerUI::GetInstance(), hRsrc); if(!hGlobal) return; LPVOID lpBuffer = LockResource(hGlobal); if(!lpBuffer) return; pRichEdit->AppendText((char*)lpBuffer); FreeResource(hGlobal); }}
可以看出,所有控件都通过绑定函数放到了集合中,在notify中找到控件来响应动作。
通过pop来接收nsis参进来的参数,push来给nsis传递参数。
在nsis中调用语法如下所示
这是绑定安装界面控件事件格式
nsDui::FindControl "btnSelectDir" Pop $0 ${If} $0 == 0 GetFunctionAddress $0 OnBtnSelectDir nsDui::OnControlBindNSISScript "btnSelectDir" $0 ${EndIf}
在安装逻辑中使用格式如下
Function OnBtnSelectDir nsDui::SelectInstallDir Pop $0FunctionEnd
参考wyrover的代码,感谢,获取源码请点击此链接
阅读全文
0 0
- 通过nsis和duilib实现自定义安装界面
- NSIS自定义界面修改
- NSIS 自定义安装界面准确获取安装进度完美解决方案
- NSIS 自定义安装界面准确获取安装进度完美解决方案
- NSIS 自定义安装界面准确获取安装进度完美解决方案
- DuiLib实现自定义控件
- Duilib 界面库的窗口类型和实现方法
- NSIS 自定义安装部署实例
- 提供修复界面的NSIS安装包
- nsis制作新版迅雷安装界面
- NSIS安装界面无虚线框移动
- duilib 界面库 实现timer定时器
- 实现自定义Silverlight的安装界面
- NSIS 自定义界面布局简介 (学习四)
- 修改mfc程序图标、利用DUILIB库自定义界面
- nsis接收命令行参数,实现动态安装
- NSIS 安装界面前端显示(设置TOPMOST属性)
- NSIS 自定义页面结合组件选择安装(二)
- Spring MVC框架环境的搭建
- 深度学习—传统神经网络总结
- C/C++出现Debug Assertion Failed!错误
- 【ubuntu】系统崩溃(系统空间满了,sudo不可用,不能联网等)解决方法
- Spring笔记
- 通过nsis和duilib实现自定义安装界面
- ODI-1228: Caused By: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
- myeclipse快捷键
- Swift 运算符
- Material Design 原来这么有趣
- Unity3D本地数据存储读取
- JVM(java 虚拟机)内存设置
- call函数的来源
- CentOS环境下jdk的安装与配置