有部分是参照网上给出的例子
1. 创建无任务栏图标的应用程序
创建无任务栏显示的应用(通过代码删除任务栏图标) 适用于多个窗口的业务场景
BOOL xxxxForm::HideTaskBar(HWND hwnd, BOOL bShow)
{
HRESULT hr;
ITaskbarList* pTaskbarList;
hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER,
IID_ITaskbarList, (void**)&pTaskbarList);
if (SUCCEEDED(hr))
{
pTaskbarList->HrInit();
if (bShow)
pTaskbarList->AddTab(hwnd);
else
pTaskbarList->DeleteTab(hwnd);
pTaskbarList->Release();
return TRUE;
}
return FALSE;
}
2. 获取托盘图标的位置 (这种适用某种状态展示 在托盘的上方的业务场景)
//获取托盘的句柄
HWND hWnd = NULL;
HWND hWndPaper = NULL;
if ((hWnd = FindWindow(_T("Shell_TrayWnd"), NULL)) != NULL)
{
if ((hWnd = FindWindowEx(hWnd, 0, _T("TrayNotifyWnd"), NULL)) != NULL)
{
hWndPaper = FindWindowEx(hWnd, 0, _T("SysPager"), NULL);
if (!hWndPaper)
hWnd = FindWindowEx(hWnd, 0, _T("ToolbarWindow32"), NULL);
else
hWnd = FindWindowEx(hWndPaper, 0, _T("ToolbarWindow32"), NULL);
}
}
//获取浮窗的位置 然后show tips
RECT rect;
::GetWindowRect(hWnd, &rect);
3. 拖拽功能实现
Step1 在InitWindow函数中 增加如下代码
//使窗口具有接收文件的能力
::DragAcceptFiles(this->m_hWnd, true);
Step2 在事件处理中 捕获 WM_DROPFILES 这个事件 来处理拖拽
Step3 拖拽后 会得到对应的文件路径 通过这个信息来做相应的业务
处理文件的路径的业务代码如下
HDROP hdrop = HDROP(wParam);
wchar_t sDropFilePath[MAX_PATH];
int iDropFileNums = 0;
std::list<std::string> lFilePath;
iDropFileNums = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);//获取拖放文件个数
for (int i = 0; i < iDropFileNums; i++)//分别获取拖放文件名(针对多个文件操作)
{
DragQueryFile(hdrop, i, sDropFilePath, sizeof(sDropFilePath));
OutputDebugString(sDropFilePath);
OutputDebugString(L"\n");
lFilePath.push_back(nbase::UTF16ToUTF8(sDropFilePath));
}
DragFinish(hdrop);//释放文件名缓冲区
通过这种方式 可以获取到 拿到多个文件的路径,这里是从duilib中截取的一段代码
4. 检测网络状况(适用于工程中的断网重连的 场景)
用法比较简单 直接上代码 就是一些win32接口的使用
//2021-07-30 11:26:57 JamesWu add 检测网络的模块
#include <Wininet.h>
#pragma comment (lib, "Wininet.lib")
#include <Sensapi.h>
#pragma comment (lib, "Sensapi.lib")
#include <shellapi.h>
bool xxxxxForm::CheckNetStatus()
{
DWORD flags;//上网方式
BOOL bOnline = TRUE;//是否在线
bOnline = IsNetworkAlive(&flags);
return bOnline;
}
5. duilib中的圆形图标实现问题 (用于登录或者 标题栏状态展示的业务场景)
核心思想 就是通过一个 图层 来控制 通过一个圆形图框 来与展示的控件重合
例子:
<Box width="auto" height="auto" halign="center" >
<Control name="user_image" margin="0,16" halign="center" width="40" height="40"/>
<Control class="icon_headimage_mask_40x40" margin="0,16" name="head_image_mask" mouse="false"/>
</Box>
这里的圆形图 类似
6. curl的一个下载属性设置
这里涉及到一个下载的超时参数设置
摘自网络
cURL 的超时设置有两个 CURLOPT_CONNECTTIMEOUT 和 CURLOPT_TIMEOUT,他们的区别是:
- CURLOPT_CONNECTTIMEOUT 在成功连接服务器前等待多久(连接成功之后就会开始缓冲输出),这个参数是为了应对目标服务器的过载,下线,或者崩溃等可能状况。
- CURLOPT_TIMEOUT 从服务器接收缓冲完成前需要等待多长时间,如果目标是个巨大的文件,生成内容速度过慢或者链路速度过慢,这个参数就会很有用。
使用 cURL 下载 MP3 文件是一个对开发人员来说不错的例子,CURLOPT_CONNECTTIMEOUT 可以设置为10秒,标识如果服务器10秒内没有响应,脚本就会断开连接,CURLOPT_TIMEOUT 可以设置为100秒,如果MP3文件100秒内没有下载完成,脚本将会断开连接。
需要注意的是:CURLOPT_TIMEOUT 默认为0,意思是永远不会断开链接。所以不设置的话,可能因为链接太慢,会把 HTTP 资源用完。
7. 非客户区的一个鼠标操作问题 (这个在非客户区 可以解决一个拖动的问题 在制作浮窗的业务场景可以使用)
LRESULT SFloatForm::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int ret = 0;
switch (uMsg)
{
case WM_NCLBUTTONDBLCLK:
OutputDebugString(L"鼠标左键双击事件被触发\n");
break;
case WM_NCRBUTTONDOWN:
OutputDebugString(L"鼠标右键单击事件被触发\n");
break;
case WM_NCMOUSEHOVER:
OutputDebugString(L"鼠标停留事件被触发\n");
break;
case WM_NCMOUSEMOVE:
{
if (_bMouseTrack)
{
TRACKMOUSEEVENT csTME;
csTME.cbSize = sizeof(csTME);
csTME.dwFlags = TME_HOVER | TME_NONCLIENT;
csTME.hwndTrack = m_hWnd;//指定要追踪的窗口
csTME.dwHoverTime = 2000; //鼠标在按钮上停留超过2秒钟,才认为状态为HOVER
::_TrackMouseEvent(&csTME); //开启Windows的WM_MOUSELEAVE,WM_MOUSEHOVER事件支持
_bMouseTrack = FALSE; //若已经追踪,则停止追踪
}
}
break;
case WM_NCMOUSELEAVE:
_bMouseTrack = TRUE;
OutputDebugString(L"鼠标离开事件被触发\n");
break;
default:
break;
}
return __super::HandleMessage(uMsg, wParam, lParam);
}