记录下最近win端项目的几个小知识点

有部分是参照网上给出的例子

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);
}

Guess you like

Origin blog.csdn.net/Wuzm_/article/details/119455867