我正在开发一个 UI库,由
D2D
,DWrite
和Wic
提供支持,适用于(SDK API)原生C ++桌面应用程序 (就像没有XAML,没有WinRT,只是旧学校C ++)。我已准备好编写无窗口UI ,以便为我的C++
工具提供更现代的(如本世纪的外观)。
我是一名内心的后卫,所以我花了很少的时间在用户界面上,并且大部分都与Windows Standard& amp; Common Controls和一些自定义绘制的GDI东西。无论如何,没什么特别的。
我目前正在试验D2D
,我有兴趣了解UI动画的标准方法。就像当你将鼠标悬停在一个按钮上,使边框发光一点,或者一个UI元素由于交互而平滑移动,或者某些东西从屏幕上消失。 (想想jQuery在UX的经济中消失,滑动以及如此短暂但有意义的动画)
想到这一点,我想到了两种处理用户界面动画的方法:
备用线程工作者方法似乎是一个很好的方法......但是当视觉属性更新时需要一些互锁,因此在实际绘制时不会发生这种情况,以保持一致。
现在,对于单线程用户界面......计时器似乎是解决方案。这样可以确保绘图不会与动画计算重叠。但对我来说,感觉很尴尬。我不习惯单线生活方式。 :)
还有其他办法吗?或者推荐哪种方法?我很欣赏有关现有实施细节或阅读材料的任何信息。
PS :如果downvoters或那些请求关闭的人真的会给出理由,我会很感激。 (1)如果你不知道我在问什么,那就继续......这绝对不是你的问题。 (2)如果这对你来说太明显/简单,那就回答吧。 ---除非你是巨魔,否则我没有看到第三个原因。 ---或者这是一个非常愚蠢的问题,但正如我所说,我是十年+后卫,所以我可以逃脱它。
答案 0 :(得分:5)
嗯,Windows似乎有一个适用于所有内容的API。 :)强>
我刚刚找到Windows Animation Manager。它不仅可以满足我的需求,而且在页面的最后,它有一些非常好的视频,解释了UI动画概念以及它们如何与Animation Manager
一起使用。它是一组专为C ++使用而设计的COM对象。
PS :作为奖励,它独立于图形平台。所以它适用于GDI,GDI +,Direct2D ......
PPS :一天后,我已经咬了牙,这非常好。我得到的图形元素可以预测地以最少的代码在屏幕上移动。这是逻辑。一个问题是它只能为DOUBLE值设置动画。因此它对POINT,RECT,SIZE,POLYGON,多个FLOAT,PATH等没有任何概念或支持。一旦我理解它是如何正常工作的,我将包装它并添加对上述数据类型的支持,我是完成。
答案 1 :(得分:2)
我无法告诉你标准方式,但 WPF 方式(以及我认为的Java Swing方式)是有一个名为 UI线程,其唯一的工作是执行调度程序循环。调度程序循环对于队列(含糖)来说只是一个奇特的词。该框架将为该队列上的每个帧安排绘制函数。如果您想要动画,则必须在该队列上安排这些微小的逐步更新。这是因为WPF之类的东西不希望在UI线程上锁定/阻塞,而且他们也不想要竞争条件。
所以回答你的问题:它既不是一个不同的线程,也不是一个计时器。它是一个执行动画步骤的调度程序。
答案 2 :(得分:2)
GUI中没有标准。 C ++也没有gui。现在有线程,但是:)
对于严肃的gui来说,可能的选择是C#或Qt。对于较小的东西winapi + gdi或小型跨平台的c ++ gui工具包。
对于Windows上的任何非控制台编程,请熟悉“窗口过程”和winapi消息循环。首先在visual studio中创建一个新的默认win32项目并查看它生成的代码。不要这样写。请注意以下模式:
// Handles window messages. Gets called by the DispatchMessage indirectly.
LRESULT __stdcall WindowProc(HWND hWnd, UINT msg, WPARAM, LPARAM)
{
switch(msg) {
case WM_PAINT: BeginPaint(...);
// Some GDI drawing might go here
EndPaint(...); break;
case WM_TIMER: InvalidateWindow(hWnd); break;
case WM_DESTROY: PostQuitMessage(0); break;
default: return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int __stdcall WinMain(HINSTANCE, HINSTANCE, char *cmdLine, int cmdShow)
{
// create your gui here
HWND hWnd = CreateWindow(...);
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
// Main message loop : make the gui "run"
MSG msg = {0};
while(GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// Handles window messages. Gets called by the DispatchMessage indirectly.
LRESULT __stdcall WindowProc(HWND hWnd, UINT msg, WPARAM, LPARAM)
{
switch(msg) {
case WM_PAINT: BeginPaint(...);
// Some GDI drawing might go here
EndPaint(...); break;
case WM_TIMER: InvalidateWindow(hWnd); break;
case WM_DESTROY: PostQuitMessage(0); break;
default: return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
int __stdcall WinMain(HINSTANCE, HINSTANCE, char *cmdLine, int cmdShow)
{
// create your gui here
HWND hWnd = CreateWindow(...);
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
// Main message loop : make the gui "run"
MSG msg = {0};
while(GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
这是原生的winapi应用程序框架。这就是MFC / ATL / Qt所做的事情。 Winapi提供了一些开箱即用的基本控件:窗口,文本框,按钮,单选按钮,选择按钮,列表框。所有人都做了基本的阴影,突出了焦点 - 自win95以来可用的东西,但不是更多。如果gui非常谦虚,那么你可以使用普通的winapi来逃避它。
作为一个gui库开发人员,最好的组合可能是来自ms或其他供应商的win32 api和com组件。
答案 3 :(得分:2)
我知道它的死灵法(我经常这样做),而且你已经接受了你的答案......但你或其他读者可能有兴趣看看DirectComposition。请注意它的Windows 8 + 。
Microsoft DirectComposition是一个启用的Windows组件 高性能位图组合,具有变换,效果和 动画。