当前位置: 首页 > news >正文

2501wtl,皮肤技术

下载地址

设计目标

最重要的是使用方便,已有程序创建一个COM对象,调一个方法就可把界面外观全部改成Mac风格的.
另外一个目标要有扩展性.

所以,基本设计定义一个统一的接口,然后用不同实现.每一个实现单独放在一个COMDLL中,调用者选择一个类标创建对象就行了.
接口的定义:

 interface ISkinX : IUnknown{[helpstring("Install Skin hook")] HRESULT InstallSkin([in] long lThreadID);[helpstring("Uninstall Skin hook")] HRESULT UninstallSkin();};

调用InstallSkin安装皮肤,UninstallSkin卸掉皮肤,lThreadID是线程ID.

原理

就是通过消息勾挂改变已有控件外观.

好处是可不必修改程序完成的标准界面,只要勾挂上勾挂函数,所有的界面都变了,使用起来非常方便.

原理就是下面的调用:

SetWindowsHookEx(WH_CALLWNDPROC, HookProc, 0, lThreadID);

WH_CALLWNDPROC勾挂,可拦截所有线程IDlThreadID线程内的窗口消息,这样就可处理这些消息.

但是,光拦截消息还不够,还必须知道是谁发出的这些消息.
幸好,从消息的参数里,可得到窗口句柄,而通过窗口句柄,可得到窗口类.这里说的窗口类窗口系统中的窗口类名.

如,按钮的窗口类"按钮",组合框的窗口类"ComboBox"...这些在MSDN里面都可找到的,另外,还有一些文档中没有的窗口类名,比如对话框,有一个叫"#32770"的类名,而菜单,实际上也是一个窗口,其类名"#32768".

有了这些信息,就可区分不同窗口处理了.
处理消息,显然最重要的是WM_PAINT消息.这样可重载系统默认的绘画方式,把控件窗口画成想要的样子.

但是只处理WM_PAINT消息也是不够的,因为控件的风格不是一成不变的,看看窗口xp的显示效果,以按钮为例,有很多种风格,普通风格,鼠标在按钮上的风格,鼠标按住按钮的风格,鼠标按住按钮又移动到按钮外的风格

为了实现动态炫目皮肤效果,还需要截取一些其他消息,如鼠标消息.下载代码里有Mac按钮的一个实现,看一下就知道了.

有了勾挂,就可截取所有消息,有了窗口类,就可识别窗口类型,对不同类型的窗口给予不同处理.

这样,要在勾挂函数里面识别不同窗口和不同消息,有大量的分发工作,更重要的是,光区分窗口类还不够,同类型不同窗口经常需要不同处理,如两个按钮窗口,大小不同,文字不同,是否有鼠标按下不同.

这些状态有些是可从按钮窗口读到的,如大小和文字,而有些则读不到,比如是否按下鼠标,对这些读不到的状态,必须自己记录,如在收到WM_LBUTTONDOWN消息时记下按下了按钮.

也即,对每个窗口,还需要记录一些与其相应的数据,这样在收到WM_PAINT消息时做不同处理.把所有这些逻辑写在勾挂函数显然太麻烦了,即使写出来也没法维护,需要一个好的设计.

根据面向对象的思想,需要为每种窗口类型写一个类,并为每个窗口生成一个对应类的实例,由这些实例处理窗口消息,并记录必要的窗口状态数据.

这样,就由这些对象处理窗口消息,怎么给这些对象传递消息呢,可以转发勾挂函数,不过这里用了另一个:SubclassWindow,SubclassWindow的原理,就不多讲了,可参看MSDN,其实就是替换一个窗口过程函数.

ATL提供了现成的支持,用起来还是很方便的,替代的窗口过程函数不用全部自己写,而可用消息映射宏生成.

现在用SubclassWindow的方式,可直接把对象链接到窗口的消息链中,这好像有点和勾挂函数的功能重复了,因为勾挂函数本来就是用来拦截消息的.

现在SubclassWindow以后,已可拦截窗口消息,那还要勾挂函数干什么呢?

答案是:用勾挂函数来执行SubclassWindow操作.原因有两个,第一,要做的是一个皮肤插件,想用户调用一个函数就可改变整个界面风格,而不是为每个窗口调用SubclassWindow函数;

第二,创建有些窗口,根本不是在代码控制的,如菜单窗口,除了使用勾挂函数,甚至不能取得菜单窗口的句柄.

所以,必须使用勾挂函数,但在勾挂函数中,只处理一个消息:WM_CREATE,在创建一个可识别窗口时,生成一个对象实例,并用SubclassWindow勾挂该实例目标窗口,让该对象实例去完成剩下的事情.

总结一下:
1,为每种可识别的窗口类编写类,实现必要的消息处理及保存状态;
2,用勾挂函数拦截WM_CREATE消息,并创建对应的类实例;

3,通过SubclassWindow操作把生成的类实例勾挂到目标窗口,处理消息及保存状态;

PushButton绘画的问题,我冒昧对你的代码做了点修改.思路就是在子类化按钮后,将按钮风格改成自绘画,这样就不会和按钮自身的绘画干扰了,而且我估计只要处理WM_DRAWITEMWM_MEASUREITEM消息就可以了,不过我没有这么试过.

但是复选框RadioButton没有BS_OWNERDRAW风格,所以没法这么做.绘画干扰问题还没有解决.下面贴出我对CMacButton修改过的地方:
1,增加long m_iCtrlType;成员变量
2,

 void Initialize(){m_iCtrlType=-1;//..m_nState = STATE_NORMAL;m_bTracking = false;if(BASETYPE_BUTTON==GetBaseType())//..{::SetWindowLong(m_hWnd,GWL_STYLE,::GetWindowLong(m_hWnd,GWL_STYLE)|BS_OWNERDRAW);}}
3,long GetBaseType(){if(m_iCtrlType!=-1)return m_iCtrlType;//..long lStyle = GetWindowLong(GWL_STYLE);if ( (lStyle & BS_OWNERDRAW) == BS_OWNERDRAW )//`物主画`return m_iCtrlType=BASETYPE_OWNERDRAW;//..if ((lStyle & BS_GROUPBOX)==BS_GROUPBOX)//组框return m_iCtrlType=BASETYPE_GROUPBOX;else if ((lStyle & BS_CHECKBOX)==BS_CHECKBOX|| (lStyle & BS_AUTOCHECKBOX) == BS_AUTOCHECKBOX  )//复选框return m_iCtrlType=BASETYPE_CHECKBOX;else if ((lStyle & BS_AUTORADIOBUTTON)==BS_AUTORADIOBUTTON|| (lStyle & BS_RADIOBUTTON)==BS_RADIOBUTTON)//收音机return m_iCtrlType=BASETYPE_RADIOBUTTON;//普通按钮return m_iCtrlType=BASETYPE_BUTTON;}

这样,要为每种需要改变外观控件窗口编写一个类,很自然的想到取出它们的公共基类,这就是CWidgetHookBase,所有控件窗口处理类的公共基类,实际上是一个C++接口,因为它只包含一个纯虚函数,下面是它的定义:

组件勾挂的抽象基类
class CWidgetHookBase
{
public:virtual void Install(HWND hWidget) = 0; //在`CWidgetHook`中实现
};

该接口中唯一的安装函数,用来实现把对象链接到窗口的功能,也就是SubclassWindow,这会在继承类实现.

这里要讲的实际上是控件类工厂,也就是CWidgetFactory其继承类.下面是CWidgetFactory完整声明和实现:

///用来勾挂`组件`的抽象工厂类.创建`勾挂`实例
class CWidgetFactory
{
protected:static CWidgetFactory* m_pInstance;
public://初化实例CWidgetFactory(){ATLASSERT(m_pInstance==NULL);m_pInstance = this;}//取单例实例static CWidgetFactory* Instance(){return m_pInstance;}virtual CWidgetHookBase*    CreateWidget(LPCTSTR szClass) = 0;
};
CWidgetFactory* CWidgetFactory::m_pInstance = NULL;

CWidgetFactory使用了两个设计模式,单件模式和抽象工厂模式,实际上还包括抽象方法模式.

首先看抽象工厂模式,想让控件工厂根据窗口的名字创建不同控件窗口消息处理类.对仿真Mac的系统,这些控件窗口消息处理类包括CMacButton,CMacComboBox,CMacTrackBar等;

而对仿真KDE的系统,则是CKDEButton,CKDEComboBox等.这样,就可定义两个CWidgetFactory的继承类,分别叫CMacFactoryCKDEFactory,分别产生这两个族的对象.

CWidgetFactory::CreateWidget就是用来产生这些对象的方法,它是个必须在继承类中实现纯虚函数.CreateWidget接受窗口的名字为参数,返回所有控件类的基类CWidgetHookBase指针.

这样,每个对象工厂负责产生一族对象,但对一个应用来说,应该只有一个风格,也即,只有一个工厂的实例,单件模式来了.

这里使用简化版的单件模式,需要声明一个继承类的实例,然后通过CWidgetFactory实例静态函数得到该唯一实例.

这里没有控制不能生成第二个实例,不过问题不大.
现在来看工厂的一个实现,CMacFactory,完整的代码如下:

class CMacFactory : public CWidgetFactory
{
public:virtual CWidgetHookBase*    CreateWidget(LPCTSTR szClass){if (lstrcmpi(szClass, "Button") == 0 )return new CMacButton;else if (lstrcmpi(szClass, "#32770") == 0) //对话return new CMacDialog;else if (lstrcmpi(szClass, "ListBox") == 0)return new CMacListBox;else if (lstrcmpi(szClass, WC_TABCONTROL) == 0)return new CMacTabCtrl;else if (lstrcmpi(szClass, "#32768") == 0) //菜单return new CMacMenu;else if (lstrcmpi(szClass, "ComboBox") == 0) //组合框return new CMacCombo;else if (lstrcmpi(szClass, TRACKBAR_CLASS) == 0) //跟踪杆return new CMacTrackBar;return NULL;}
};

再看看消息勾挂的代码:

LRESULT CALLBACK CMacSkin::HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{CWPSTRUCT cwps;if( nCode == HC_ACTION ){CopyMemory(&cwps, (LPVOID)lParam, sizeof(CWPSTRUCT));switch(cwps.message){case WM_CREATE:{CHAR szClass[MAX_PATH];GetClassName(cwps.hwnd, szClass, MAX_PATH);CWidgetHookBase*   pWidget=NULL;pWidget = CWidgetFactory::Instance()->CreateWidget(szClass);if (pWidget)pWidget->Install(cwps.hwnd);}break;}}return CallNextHookEx((HHOOK)CMacSkin::m_hHook, nCode, wParam, lParam);
}

不管对CMacFactory还是其他的工厂实现,及不同控件类族,勾挂函数的实现都是一样的.CWidgetFactory继承类的实现也类似,只是替换一些类名而已.

现在,有了控件类的接口:CWidgetHookBase,产生控件对象的工厂也有了,下面就该实现控件类了.在定义控件基类时,只定义了一个抽象安装函数,而没有其他代码,则,所有实现代码都交给各个控件类去实现吗?

不是,这些控件类还有许多公共代码可在基类实现,但是,选择不在CWidgetHookBase加入这些代码,而是再加入一个中间类:CWidgetHook.

不可把这两个基类合为一个类呢?其实,最初的设计是只有一个基类的,就是CWidgetHook,而又想在继承类中使用WTL包装窗口控件的类,这样,根据ATL/WTL的架构,CWidgetHook就必须是一个模板类,而模板类是不能作为基类指针的,因为模板是类型不定的,而抽象工厂模式要求一个基类指针,所以又取出CWidgetHookBase纯虚的接口类.

下面是CWidgetHook模板类的声明:

//`//`所有`组件`勾挂的基类/参数:`/T/`继承类`/TBase/Widget`窗口包装器,为了方便,使用`WTL`包装器template <class T, class TBase = CWindow>
class CWidgetHook : public CWidgetHookBase, public CWindowImpl<T, TBase>
//CRTP

这里用了多继承,它也是ATL里常用的,第一个父类前面定义的CWidgetHookBase接口,需要该接口实现抽象工厂设计模式.

第二个父类CWindowImp,这是ATL定义的,是所有窗口类的(虽然不是顶层)高层父类.

CWindowImp接收两个模板参数,同时也是CWidgetHook模板参数.第一个模板参数继承类,这也是ATL中常用的技巧,该技巧使得可在父类中知道继承类的类型,于是,把指针转换成继承类的类型,就可调用继承类的方法,这样实现了类似虚函数的多态,却不需要付出虚函数的性能代价.

追踪ATL的代码,可见其实TBase参数最终是作为基类的,通过模板参数改变基类,这也是模板OO不同的地方.

TBase有一个默认CWindow值,可在此传入其他类,但必须是CWindow继承类,最有价值的参数当然是WTL窗口包装类,这样,在实现控件消息处理类时,就可用WTL包装类提供的功能,而不需要只依赖窗口接口了,确实可带来不少帮助.

讲完CWidgetHook的声明.下面来看CWidgetHook定义和实现,首先看几个函数声明:

 void Initialize() {}; //初化实例void Finalize() {};    //实例`终止器`static void InitializeClass() {}; //初化类static void FinalizeClass() {};  //类的`终止器`

上面四个函数包含了空的实现,在继承类可选择重载它们.
生成每个实例时,调用初化,在析构实例前,调用终止器;在生成类的第一个实例时调用InitializeClass静态函数,在析构类的最后实例时调用FinalizeClass.

为什么要有两个静态函数呢,因为一个类代表同一个窗口,这些窗口会使用同样的资源,如复选框,需要几张不同状态的图片,而这些图片对每个复选框来说都是一样的,如果为每个实例保存这样一份资源,就有点浪费内存了.

对一个皮肤插件来说,效率还是很重要的,所以选择用静态变量保存这些图片,并在第一个生成复选框时,加载这些资源,后续生成的其他复选框重用这些资源,然后在最后复选框消失时释放这些资源,这样,最小化了内存的使用量.

构造器和析构器调用这两个静态函数,另外还有个m_lRef实例计数值,下面还剩下OnFinalMessage安装函数没讲.

OnFinalMessage比较简单,调用Finalize删除自己,因为是CWindowImp继承类,OnFinalMessage函数会在析构窗口时自动调用它,这样,就保证了会自动释放实例,不会造成泄漏内存.

最后看安装函数,这是在CWidgetHookBase中定义的纯虚函数,在CWidgetHook模板类中实现它.

安装函数的主要功能是调用SubclassWindow,从而控制窗口消息.另外,还控制反射消息和初化实例.
下面是它的代码:

 virtual void Install(HWND hWidget){ATLASSERT(::IsWindow(hWidget));SubclassWindow(hWidget);//如果它是子窗口,请为其父窗口安装一个`反射器`,这样`父窗口`会反射回消息给我if ( (::GetWindowLong(hWidget, GWL_STYLE) & WS_CHILD) == WS_CHILD){HWND hWndParent = ::GetParent(hWidget);ATLASSERT(::IsWindow(hWndParent));// `WM_GETREFLECTOR`取已安装的反射器(如果有)CReflectHook* pReflector =(CReflectHook*)::SendMessage(hWndParent, WM_GETREFLECTOR, 0, 0);if (!pReflector)new CReflectHook(hWndParent);}T* pT = static_cast<T*>(this);pT->Initialize();//继承类要实现.在此针对性的初化.}

安装函数是模板方法,它调用的初化方法则要在继承类中重载.则,初化方法是实例的初化函数,不可放在构造器里呢?

因为每个实例初化可能不太一样,要根据被勾挂的窗口的状态决定,所以,必须等到调用SubclassWindow后,才调用初化方法,在继承类初化实现中,可通过m_hWnd直接取得窗口句柄,调用APIWTL包装类方法检查窗口状态,并执行必要的实例初化代码.

MFCATL都提供了反射消息的机制,就是让父窗口收到这类消息时,把它们再返回给控件窗口,这就是反射消息.

要实现皮肤插件,也需要在控件窗口类收到这些消息,但是,不能依赖ATLMFC的反射,因为想可让不同主机程序使用皮肤插件,而不是局限于ATLMFC.

其他程序可能没有反射消息机制,或使用了不同反射消息机制.所以,实现了自己的反射消息机制.

CReflectHook类就是用来完成反射消息的,其构造器按参数接受父窗口的句柄,然后调用SubclassWindow对象实例链接到窗口上去,这和控件的实现类似.

ProcessWindowMessage是个虚函数,它的定义可追述到ATL窗口类的最底层,CReflectHook::ProcessWindowMessage实现反射功能,把收到需要反射的消息返回给控件窗口.

但也不是简单的原样返回,而是包装成另一个WM_REFLECT消息,以免和其他消息冲突.当反射消息发回给控件窗口时,控件窗口利用下面三个宏展开WM_REFLECT,并得到原消息:

LF_REFLECTED_NOTIFY_CODE_HANDLER
LF_REFLECTED_COMMAND_CODE_HANDLER
LF_REFLECTED_MESSAGE_HANDLER

另外注意WM_GETREFLECTOR消息,可用该自定义消息来向父窗口查询与其关联的CReflectHook实例,以避免重复安装反射勾挂,因为CReflectHook::ProcessWindowMessage该消息返回了指针.
CWidgetHook::Install使用了WM_GETREFLECTOR消息.

最后说一下怎么写CWidgetHook继承类(即控件类),这也是直接影响最终效果的.WTL定义了许多常见控件包装类,把这些类作为CWidgetHook第二个模板参数,可以大大简化后续工作,当然,如果没有对应的包装类,也可接收默认参数.

因为借助了ATL/WTL基本架构,编写控件类和写一个ATL窗口类类似,可用ATL/WTL消息映射宏,当然,不象MFC一样提供了向导,需要手动输入这些宏.

另外,控件类还可选择的重载CWidgetHook定义的4个初化和清理函数.附带示例提供了一个Mac按钮类的实现,可参考,该按钮示例算是比较复杂的,因为窗口窗口类名为"按钮"的窗口,实际上包括普通按钮,单选钮和复选框,其他的许多控件实现起来比按钮容易,当然也有一些比较麻烦的.

相关文章:

2501wtl,皮肤技术

下载地址 设计目标 最重要的是使用方便,已有程序创建一个COM对象,调一个方法就可把界面外观全部改成Mac风格的. 另外一个目标是要有扩展性. 所以,基本设计是定义一个统一的接口,然后用不同实现.每一个实现单独放在一个COMDLL中,调用者选择一个类标创建对象就行了. 接口的定义…...

【面试题】技术场景 6、Java 生产环境 bug 排查

生产环境 bug 排查思路 分析日志&#xff1a;首先通过分析日志查看是否存在错误信息&#xff0c;利用之前讲过的 elk 及查看日志的命令缩小查找错误范围&#xff0c;方便定位问题。远程 debug 适用环境&#xff1a;一般公司正式生产环境不允许远程 debug&#xff0c;多在测试环…...

word论文排版常见问题汇总

word论文排版常见问题汇总 常用快捷键&#xff1a; Alt F9 正常模式与域代码模式切换 Ctrl F9 插入域代码 F9 刷新域代码显示&#xff0c;要注意选定后刷新才会有效果 word中在当前列表的基础上修改列表 在使用word时&#xff0c;我们会定义一个列表&#xff0c;并将其链接…...

传奇3仿韩服单机版安装教程+GM管理面板

今天为大家带来一款怀旧网单《传奇3仿韩服》的游戏架设&#xff0c;适用于单机娱乐&#xff0c; 仅供怀旧&#xff0c;本人已经安装游戏成功&#xff0c;特此带来详细安装教程。 适用环境 单机 视频演示 传奇3仿韩服单机 亲测截图 架设步骤 关闭默认杀毒软件和其它自己下的杀…...

第26章 汇编语言--- 内核态与用户态

汇编语言是低级编程语言的一种&#xff0c;它与特定计算机的硬件架构紧密相关。内核态和用户态是操作系统中进程运行的两种不同模式&#xff0c;它们用来区分操作系统内核代码和其他应用程序代码的执行环境。下面我将简要解释这两种状态&#xff0c;并给出一个简单的示例来展示…...

Spring bean的生命周期和扩展

接AnnotationConfigApplicationContext流程看实例化的beanPostProcessor-CSDN博客&#xff0c;以具体实例看bean生命周期的一些执行阶段 bean生命周期流程 生命周期扩展处理说明实例化:createBeanInstance 构造方法&#xff0c; 如Autowired的构造方法注入依赖bean 如UserSer…...

计算机网络 (33)传输控制协议TCP概述

一、定义与基本概念 TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。它工作在OSI模型的第四层&#xff0c;即传输层&#xff0c;为用户提供可靠的、有序的和无差错的数据传输服务。TCP协议与UDP协议是传输层的两大主要协议&#xff0c;但两者在设计上有明显的不同&…...

Python3 JSON

JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成。它基于JavaScript编程语言的一个子集&#xff0c;但JSON是独立于语言的&#xff0c;很多编程语言都支持JSON格式数据的…...

Leetcode 698 Partition to K Equal Sum Subsets

题意 给一个数组&#xff0c;要求把数组里的元素分成k个子集&#xff0c;满足每个子集中数的总和是相等的。问是否能分成k个子集 题目链接 https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/ 思考 想象你有k个桶&#xff0c;然后你有n个小球&…...

可靠的人形探测,未完待续(III)

一不小心&#xff0c;此去经年啊。问大家新年快乐&#xff01; 那&#xff0c;最近在研究毫米波雷达模块嘛&#xff0c;期望用在后续的产品中&#xff0c;正好看到瑞萨的活动送板子&#xff0c;手一下没忍住。 拿了板子就得干活咯&#xff0c;我一路火花带闪电&#xff0c;开整…...

Git文件夹提交错了,怎么撤销?

最近提交了一些不应该提交的文件夹到git中,现在需要移除它们,现在简单记录一下操作日志: 情况一 文件夹已经被添加到 Git&#xff0c;但未提交 如果文件夹已经被 git add 添加到暂存区中&#xff0c;但尚未提交&#xff0c;你可以使用以下命令将其从暂存区中移除: git rm -r …...

小程序textarea组件键盘弹起会遮挡住输入框

<textarea value"{{remark}}" input"handleInputRemark" ></textarea> 如下会有遮挡&#xff1a; 一行代码搞定 cursor-spacing160 修改后代码 <textarea value"{{remark}}" input"handleInputRemark" cursor-spacin…...

Android车机DIY开发之学习篇(二)编译Kernel以正点原子为例

Android车机DIY开发之学习篇(二)编译Kernel以正点原子为例 1.代码在/kernel-5.10文件夹下 2.在kernel-5.10目录下执行如下命令编译 &#xff1a; 编译之前&#xff0c;需要将 clang 导出到 PATH 环境变量&#xff1a; 如果是 Android12 执行下面这条命令 export PATH../pr…...

qt 窗口(window/widget)绘制/渲染顺序 QPainter QPaintDevice Qpainter渲染 失效 无效

qt窗体布局 窗体渲染过程 qt中窗体渲染逻辑顺序为 本窗体->子窗体/控件 递归&#xff0c;也就是说先渲染父窗体再渲染子窗体。其中子窗体按加入时的先后顺序进行渲染。通过下方的函数调用堆栈可以看出窗体都是在widget组件源码的widgetprivate::drawwidget中进行渲染的&am…...

Ubuntu下载时不显示无线网图标并显示Cable unplugged

我用的是ubuntu22-04-5.iso一下载出来发现无法连接网络甚至直接显示Wired是Cable unplugged. 下面是解决方法&#xff1a; step1: step2:点击编辑中的虚拟网络编辑器 step3: step4: step5: step6:取消勾选自动检测可用的DNS服务器 step7&#xff1a;在window上按下winR输入c…...

微信小程序实现人脸识别登录

hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生…...

atoi函数的概念和使用案例

atoi 函数是 C 语言标准库中的一个函数&#xff0c;它用于将字符串转换为整数。atoi 的名称是 “ASCII to integer” 的缩写。该函数定义在 <stdlib.h> 头文件中。 概念 atoi 函数会从字符串的开始位置开始转换&#xff0c;直到遇到第一个非数字字符或遇到字符串结束符…...

Mysql--运维篇--日志管理(连接层,SQL层,存储引擎层,文件存储层)

MySQL提供了多种日志类型&#xff0c;用于记录不同的活动和事件。这些日志对于数据库的管理、故障排除、性能优化和安全审计非常重要。 一、错误日志 (Error Log) 作用&#xff1a; 记录MySQL服务器启动、运行和停止期间遇到的问题和错误信息。 查看&#xff1a; 默认情况下…...

poi处理多选框进行勾选操作下载word以及多word文件压缩

一、场景 将数据导出word后且实现动态勾选复选框操作 eg: word模板 导出后效果&#xff08;根据数据动态勾选复选框&#xff09; 二、解决方案及涉及技术 ① 使用poi提供的库进行处理&#xff08;poi官方文档&#xff09; ② 涉及依赖 <!-- excel工具 --><depen…...

QT 键值对集合QMap

在QT中&#xff0c;可以使用QMap作为键值对的集合。QMap是Qt的一个模板类&#xff0c;它存储了键值对&#xff0c;并且可以通过键来快速查找值。 导入 #include <QMap> 以下是一些使用QMap的方法&#xff1a; 1.创建并初始化一个 QMap<int, QString> UserDepa…...

NetMQ里Push-Pull模式,消息隔一收一问题小记

问题&#xff1a; 本机环境下&#xff0c;在push端向pull端发送消息的过程中&#xff0c;发现同一个进程里的pusher和puller代码&#xff0c;可以准确地完成收发&#xff1b; 然而&#xff0c;将代码放在两个进程里&#xff0c;将pusher发送的消息从1计数&#xff0c;puller端竟…...

见微知著:Tripo 开创 3D 生成新时代

关于 VAST VAST 成⽴于 2023 年 3 ⽉,是⼀家致⼒于通⽤ 3D 大模型研发的 AI 公司,公司⽬标是通过打造⼤众级别的 3D 内容创作⼯具,建⽴ 3D 的 UGC 内容平台,让基于 3D 的空间成为⽤户体验、内容表达、提升新质⽣产⼒的关键要素。 2024 年初,VAST 推出数⼗亿参数级别的 3…...

消息队列与中间件:Java的秘密传输带

消息队列与中间件技术是分布式系统中的重要组件&#xff0c;它们主要解决应用耦合、异步消息处理、流量削峰等问题&#xff0c;并实现高性能、高可用、可伸缩和最终一致性的架构。 2.1 消息队列的基本概念 消息队列是一种应用程序间传递消息的技术&#xff0c;它允许应用程序发…...

Bytebase 3.1.0 - 通过 Google / GitHub SSO 功能开放给专业版

&#x1f680; 新功能 支持在 PostgreSQL DML/DDL 工单中选择执行角色。 在项目设置中增加 PostgreSQL 数据库租户模式配置选项。 在数据库页面和 SQL 编辑器为 ORACLE 数据库展示 package 元数据。 支持为环境配置颜色&#xff0c;方便区分。 新增管理员可关闭数据导出…...

EdgeOne安全专项实践:上传文件漏洞攻击详解与防范措施

靶场搭建 当我们考虑到攻击他人服务器属于违法行为时&#xff0c;我们需要思考如何更好地保护我们自己的服务器。为了测试和学习&#xff0c;我们可以搭建一个专门的靶场来模拟文件上传漏洞攻击。以下是我搭建靶场的环境和一些参考资料&#xff0c;供大家学习和参考&#xff0…...

k8s部署rocketmq踩坑笔记

给团队部署一个rocketmq4.8.0. k8s上部署的broker&#xff0c;注册到nameserver上是自己的pod ip&#xff0c;导致本机连接到的broker的pod ip&#xff0c;这个ip k8s集群外的机器是无法联通的。 nameserver上注册的是这个pod ipv4 尝试将broker的配置brokerIP1修改为注册到na…...

Docker 通过创建Dockerfile 部署Jar包

1、创建Dockerfile 首先确保centos 安装docker&#xff0c;参考docker安装-CSDN博客 自己找个目录来存放Dockerfile mkdir Dockerfile 2、vim Dockerfile # 使用 OpenJDK 17 基础镜像 FROM jre17:v1.0# 设置工作目录 WORKDIR /app# 暴露端口 EXPOSE 8093# 设置容器内日志目录…...

shell脚本练习

题目 1、编写一个shell 脚本&#xff0c;检测 /tmp/size.log 文件。如果存在&#xff0c;显示它的内容&#xff1b;不存在则创建一个文件&#xff0c;将创建时间写入。 2、编写一个shell 脚本,实现批量添加 20个用户&#xff0c;用户名为user1-20&#xff0c;密码为user 后面跟…...

【计算机网络】lab4 Ipv4(IPV4的研究)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;计算机网络_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2.…...

Python Json格式数据处理

示例&#xff1a;查看和编辑 JSON 文件的 Python 程序 import json from pprint import pprintdef load_json(file_path):"""加载并解析 JSON 文件。:param file_path: JSON 文件路径:return: 解析后的 JSON 对象&#xff08;字典或列表&#xff09;"&quo…...

网站备案链接直接查看/全球搜索网站排名

JsDoc 如果你在写javascript&#xff0c;是否羡慕过C&#xff0c;JAVA的文档自动生成工具&#xff1f;是否希望自己的程序也能自动生成一份对应的文档&#xff0c;犹如java API文档一样呢&#xff1f;不要再羡慕了。jsdoc_toolkit.zip 一款强大的js doc生成工具已经能完成你所羡…...

国内个人网站设计欣赏/自助建站官网

"ORA-01654: 索引VGSM.AUDIT_DATA_I无法通过8192&#xff08;在表空间KLDB中&#xff09;扩展"1.有可能是索引表空间不够select sum(bytes/1024/1024) sizeMB from dba_free_space z where z.tablespace_nameKLDB还有400M的剩余空间 应该足够。但是通过查询发现是 se…...

wordpress写插件/网络营销最基本的应用方式是什么

前言 开门见山&#xff0c;开篇明意。这篇博客主要讲解一下Android中ProgressBar控件以及间接继承它的两个子控件SeekBar、RatingBar的基本用法&#xff0c;因为其有继承关系&#xff0c;存在一些共有特性&#xff0c;所以在一篇博客中讲解。下面先简单描述一下这三个控件&…...

炫彩发光字制作网站/广东网站se0优化公司

最近一直找java8相关新特性的文章&#xff0c;发现都太没有一个连贯性&#xff0c;毕竟大家写博客肯定都有自己的侧重点&#xff0c;这里找到一本书&#xff0c;专门介绍java8新特性的&#xff0c;感觉大家可以看看《写给大忙人看的JavaSE8》.这里我会结合书中的知识以及网上的…...

网站建设 长春/google推广 的效果

Python3.x 1 数据类型 1.0 标准数据类型 Python3.x标准数据类型有6中,如下: 序号数据类型描述1数字Number2字符串String3列表List4元组Tuple5字典Dictionary6集合Set 1.2 数字(Number) 数字包括整数,浮点数,布尔数据和复数四种,python3.x中将True和False定义成关键字,表示…...

江苏企业网站定制服务/免费发外链

一、首先安装 MySQL1. 安装前更新一下仓库&#xff0c;输入命令&#xff1a;sudo apt-get updatealgerfanalgerfan:~$ sudo apt-get autoremove --purge mysql-server-5.72. 输入命令&#xff1a;sudo apt-get install mysql-server mysql-client安装MySQL数据库程序和命令行管…...