前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >minigui/mgncs:双缓冲区实现窗口推拉特效

minigui/mgncs:双缓冲区实现窗口推拉特效

作者头像
10km
发布2019-05-25 20:34:38
1.2K0
发布2019-05-25 20:34:38
举报
文章被收录于专栏:10km的专栏10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433438

minigui框架提供了窗口双缓冲区机制,利用这个机制可以实现窗口显示特效。不是所有的窗口都可以利用双缓冲区实现显示特效,窗口需要具备WS_EX_AUTOSECONDARYDC扩展窗口风格。所以下面的函数中首先就是判断窗口是否有WS_EX_AUTOSECONDARYDC扩展窗口风格。

使用miniStudio设计UI时要将SecondaryDC属性置为true,就设置了窗口的WS_EX_AUTOSECONDARYDC扩展窗口风格,如下图:

下面的screen_pull函数就是利用双缓冲区机制实现了窗口打开时从右到左推拉的显示效果。

#include <unistd.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <mgncs/mgncs.h>
#include "resource.h"
#include "ncs-windows.h"
// 获取窗口hWnd矩形坐标并转为基于屏幕的坐标
static PRECT fl_get_screen_rect(HWND hWnd, PRECT prect)
{
    GetWindowRect(hWnd,prect);
    HWND parent = GetParent(hWnd);
    WindowToScreen(parent,&prect->left,&prect->top);
    WindowToScreen(parent,&prect->right,&prect->bottom);
	return prect;
}
/**
 * 窗口水平向左推入,hwnd需要WS_EX_AUTOSECONDARYDC窗口风格
 */
static void screen_pull (HWND hwnd)
{
	// 只对双缓冲区窗口有效
	if(!(GetWindowExStyle(hwnd) & WS_EX_AUTOSECONDARYDC))
	    return;
    MSG msg;
    HDC sec_dc;

    /* 这里通过设置ON_UPDSECDC_DONOTHING,
     * 禁止ShowWindow函数将新窗口内容输出到屏幕,而只是画到SecondaryDC 
     * 再在后面的循环中将SecondaryDC中的内容一步一步画到屏幕DC.
     */
    sec_dc = GetSecondaryDC (hwnd);
    SetSecondaryDC (hwnd, sec_dc, ON_UPDSECDC_DONOTHING);

    /* get the content of the active main window */
    ShowWindow (hwnd, SW_SHOWNORMAL);
    /* wait for MSG_IDLE */
    while (GetMessage (&msg, hwnd)) {
        if (msg.message == MSG_IDLE)
            break;
        DispatchMessage (&msg);
    }
    RECT scr_rect;
    fl_get_screen_rect(hwnd,&scr_rect);
    RECT win_rect;
    GetWindowRect(hwnd,&win_rect);
	int w = scr_rect.right -scr_rect.left;
	int h = scr_rect.bottom-scr_rect.top;
    /* 直接输出到屏幕DC,实现从从右向左推拉显示,间隔100毫秒 */
    for(int shift=0;shift <= w;shift+=20)
    {
        BitBlt (sec_dc, 0, 0, shift, h,
        		HDC_SCREEN, scr_rect.right - shift, 0, 0);
        usleep (100000);
    }
    /* 函数结束时要恢SecondaryDC的默认更新方式:ON_UPDSECDC_DEFAULT */
    SetSecondaryDC (hwnd, sec_dc, ON_UPDSECDC_DEFAULT);
}

下面是参照MGNCS的ncsCreateModalDialogFromID函数写的调用示例,在执行doModal函数前调用screen_pull函数实现推拉特效 :

int myCreateModalDialogFromID (HPACKAGE package, Uint32 dlgId,
                    HWND owner,
                    NCS_EVENT_HANDLER_INFO* handlers,
					DWORD user_data)
{
    int ret = 0;
    mDialogBox * dialog = SAFE_CAST(mDialogBox,
    		ncsCreateMainWindowIndirectFromID(package,dlgId,owner,(HICON)0,(HMENU)0,handlers,user_data));
    if (dialog) {
    	screen_pull(dialog->hwnd);
        ret = _c(dialog)->doModal(dialog, TRUE);
        if(IsMainWindow(dialog->hwnd)){
        	MainWindowThreadCleanup(dialog->hwnd);
        }
    }
    return ret;
}

关于窗口双缓冲区的官方示例代码,参见 minigui示例代码库(http://www.minigui.org/downloads/mg-samples-3.0.12.tar.gz)中的mg-samples-3.0.12/dbuff文件夹

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年12月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档