系统托盘菜单点击之后500毫秒内的残影

想用C++实现一个简单的屏幕截图工具的开发,工具程序是放在系统托盘(IconTray)中的,然后通过鼠标点击托盘图标弹出菜单,再点击菜单中的截屏菜单,完成截屏操作。

软件界面如下:

一旦全屏截屏或框选区域截屏点击之后,程序就开始运行,将当前的屏幕DC保存下来,然后借助memDC将屏幕DC复制到一个bitmap中,再完成写盘操作。看上去是个非常简单的需求。

但是在Windows系统中(Win10),这个icontray的弹出菜单在点击之后并不会立即消失,我这里感觉大约会有500ms的减淡消失效果,最终导致截屏保存下来的图像,总是会带有被点击菜单的残影,如下图:

在程序里面处理其实可以有很简单的方法,就是做一个延迟处理,例如我现在延迟了0.6s、也就是600ms之后在创建screenDC:

// 立即对当前屏幕进行全屏截屏操作
void MyApp::CaptureWholeScreen(wxCommandEvent& event)
{
    wxString _imgSavePath = DatetimeUtil::getTodayScreenShotPath();
    if (PathUtil::dirExistOrMkdirSuccessful(_imgSavePath) != true)
    {
        wxLogDebug("截图存储目录不存在且无法创建,无法完成截图操作");
        return;
    }
 
    // 延迟0.6秒后将整个屏幕DC保存下来,待后面按显示器切割使用
    // @todo icontray的菜单点击后会渐变淡出,如果不设置这个0.6s的延迟,会有残影现象
    Sleep(600);
    wxScreenDC _screenDC;
 
    // 遍历每一个显示器对应的桌面,按各自桌面尺寸,从_screenDC上截取各个桌面的图像
    for (unsigned int _screenIndex = 0; _screenIndex < wxDisplay::GetCount(); _screenIndex++)
    {
        wxRect _screenGeometry = wxDisplay(_screenIndex).GetGeometry();
        wxBitmap _screenCaptureBitmap(_screenGeometry.GetSize());
 
        wxMemoryDC _memDC;
        _memDC.SelectObject(_screenCaptureBitmap);
        _memDC.Blit(wxPoint(0, 0), _screenGeometry.GetSize(), &_screenDC, _screenGeometry.GetPosition());
        _memDC.SelectObject(wxNullBitmap);
 
        wxString _filename = PathUtil::desktopTimestampFilename(_imgSavePath, _screenIndex);
        if (_screenCaptureBitmap.SaveFile(_filename, wxBITMAP_TYPE_PNG) == true)
        {
            // @todo 生成缩略图,并将图像的文件信息写入本地数据库
            // @todo 若软件主界面隐藏状态,则通知icontray弹出已生成截屏提示信息
        }
    }
}

这样就可以基本确保不会将菜单残影带进最终的截图图像中了。

但是这样的写法总是给人一种“怪怪”的感觉,心理上很难接受。它奇怪在并不是精确的控制,而是一个凭借感觉的控制——是所有的windows系统都这样吗?是所有的windows主题、所有的电脑CPU性能无论高低,都一定能在0.5s左右之后残影消失吗?

而且这个菜单残影是windows的视觉淡入淡出效果、还是我程序写的不好导致的?会不会有一个系统事件来通知我菜单真的已经彻底消失了?

不清楚,现在为了赶软件开发的进度,所以这里只能先简单粗暴的Sleep(600),等软件的整体功能全部完成之后,这里再返回头来深入的推敲一下吧。

UP4000焊接USB Type-B端子接口备忘

最近工作中用到了一台UP4000的小电脑,要从这台单板电脑(SBC)的主板上引出一个USB接口,与其他外部设备连接。

在UP4000的主板上,是有这个扩展设计的,它的CN15接口就是USB/UART扩展,这个CN15接口共有10个接线端子,其中可以引出2路USB总线。我使用的就是其中一路,也就是只使用这个接口的pin1-pin4引脚就可以了。

USB端子使用的是Type-B公口端子,线序定义网上也很容易找到。按理说从CN15到Type-B只有4条线,且这4条线的定义明确,应该很容易就搞定。但是我先后做过2批次的手动焊接,每一次都要再重新逐一核对这些线序的对应关系。想着也许今后还要再做这个工作,到时候可能又会忘记,还要再逐一核对,实在是太麻烦了。

所以干脆把这个工作做成图文,备忘一下吧。

最终的成品如下图所示,为了展示方便,所以Type-B端子那边没有用热缩管包裹。真正制作的时候是需要用热缩管对4条线的焊脚部分整体包裹、固定一下的:

UP4000单板电脑的CN15接口线序定义如下:

USB各个段子的线序定义:

最后再将焊接的示意图备忘一下。这张图右下角的手绘部分,其实更好的应该用手绘板,但是我实在犯懒、懒得起身,所以就直接用鼠标哆哆嗦嗦的画一下,估计自己今后看到的时候还能知道他们的对应关系(实际上恐怕很难,以我的经验而言,这种信手随便做的备忘,过不了多久自己再看的时候,就会忘记都是什么意思了。也许今后再做这个焊接工作的时候,我还是会再次重新回忆那边是Pin1、然后还要逐一核对这4条线是否正确)。