小编Jea*_*ond的帖子

在注册表中写入的Windows时区是否可靠?

我正在创建一个应该适用于多个时区的c ++项目.应用程序接收带有参考时区的事件,并在当地时区以正确的小时以图形方式向用户显示此事件.例如,在柏林工作的用户收到在东京写的活动.来自东京的事件首先在UTC时间转换,然后从UTC重新转换为柏林的计算机当地时间,最后在他的图形界面上向用户显示.

要将UTC转换为本地计算机时间,我可以使用Windows API的多个功能来完成这项工作.但是为了将时间从另一个时区转换为UTC,我需要从Windows注册表中获取时区信息.

现在一些时区也需要考虑夏令时.我可以毫无问题地从Windows信息创建重复规则.但是我注意到DST应该发生的那天有时候在几个时区都是不正确的.例如,"E.南美标准时间".随着Windows提供的重复发生,DST开始日期提前1周开始.

如果我理解正确,Windows为此特定时区返回的重复规则表示"每年,第2个月,在该月的第2周".但是,此规则很少与互联网上发布的更改时间的正确日期相匹配,而如果规则是"每年,第2个月,在该月的第3周",则日期都是正确的.此外,正如您在提供的屏幕截图中看到的那样,Windows注册表数据显示DST开始时间为2周(以蓝色突出显示),但DST结束时间为3周(以红色显示),这是由我的代码正确计算的.可以在此处找到数据内容的描述:http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v = vs.85).aspx

在此输入图像描述

我有几个问题

  • 我是否正确理解了重复规则?(这是MSDN所说的:https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v = vs.85).aspx)
  • 是否存在关于多个时区的已知问题,尤其是"E.南美标准时间"?
  • 有没有理由为什么DST开始日期,显然每年定期发生,在第10个月的第3周,在第2周设定值?
  • 在Windows注册表中写入的时区是否可靠,如果没有,我应该使用Windows API的哪个功能来转换带有DST的时区,而不是使用与本地计算机上设置的时区不同的时区编写的日期?

注意我在发布此消息之前已经强烈验证了我从注册表中读取的数据是否正确.我很确定这不是这种类型的错误.

注意我正在使用Windows 7,但问题在Windows 10上保持不变

c++ time timezone date dst

21
推荐指数
1
解决办法
3806
查看次数

Delphi-自XE8起如何正确注册图形类?

我正在编写一个Delphi包,该包提供了一个新的自定义TGraphic对象,从而允许在VCL组件(如TImage)中读取新的图像格式。

我最初使用RAD Studio XE7开发了此程序包,并且运行良好。但是,我最近迁移到了RAD Studio编译器的较新版本,尽管我的软件包在该新版本上仍能正常工作,但我注意到一个从未出现过的奇怪错误。

我有一个包含多个组件的表单,其中一些是TImage组件。打开IDE之后,我在设计时第一次打开项目时,所有包含我的自定义TGraphic组件的TImage组件都会立即释放其内容。如果我关闭然后重新打开该项目,图像将重新出现,并且在我关闭并重新打开IDE之前该错误不再发生。

我挖了我的代码以了解可能导致此问题的原因。要注册我的自定义TGraphic组件,我使用类初始化部分,在其中编写了以下代码:

initialization
begin
    Vcl.Graphics.TPicture.RegisterFileFormat('svg', 'Scalable Vector Graphics', TWSVGGraphic);
end;
Run Code Online (Sandbox Code Playgroud)

但是我发现,从XE8编译器版本开始,在初始化部分之前就调用了TImage构造函数,因此显然引起了上述问题。自XE8以来的所有编译器版本均会受到影响,但是此错误从未在XE7或更早版本上发生。自XE8以来,情况发生了变化。

这是我的问题:

  • 我用来注册自定义图形类的方法是否正确?
  • 如果没有,正确的方法是什么?
  • 自XE8以来似乎有所不同,注册图形组件的新正确方式是什么?
  • 还有其他人遇到过同样的问题吗?他是如何解决的?
  • 这可能是RAD Studio的新错误,还是这个问题就在我这边?

delphi components timage registration delphi-xe8

11
推荐指数
1
解决办法
232
查看次数

如何打开 HEIF (.heic) 图像?

对于 C++ 项目,我需要打开并显示 HEIF (.heic) 图像。我所知道的(如果我是对的)是 HEIF 图像基于 ffmpeg 标准,并且需要读取 H265 编解码器。

我找到了几个开源的 H265 编解码器:

我可以打开和显示 H265 编码的视频文件,但我无法简单地打开、显示或转换 .heic 图像。他们都返回一个错误,或者什么都不做。

老实说,我有点困惑,因为 HEIF 标准似乎是一个保守的秘密。我找不到可以让我找到解决方案的相关信息。我发现的那些只是技巧和变通方法,例如强制设备(我在这里谈论的是使用新 iOS11 的 Apple iPhone)生成 jpg 图像而不是 heic,或者使用像 dr.fone 这样的第三方应用程序。当然,这些解决方案与我无关。

所以,有人可以告诉我应该对 .heif 图像使用哪种编解码器,以及如何使用它来打开它?或者是否有允许操作此类图像文件的开源库或示例?有人可以为我指出好的方向吗?

ffmpeg image codec heif

8
推荐指数
1
解决办法
1万
查看次数

Delphi - 从 Rio 10.3.3 开始如何正确注册自定义图形类

所以我正在开发一个图形库,提供一个自定义的 SVG 图像格式,可以在 TPicture 或任何支持图形图像的 VCL 组件中使用,例如 TImage。我从 XE7 编译器版本开始编写和维护我的库包,我的代码向后兼容直到 XE2 版本。

为了向 IDE 声明我的自定义图形格式,我从initialization我的图形类部分调用以下代码

Vcl.Graphics.TPicture.RegisterFileFormat('svg', 'Scalable Vector Graphics', TWSVGGraphic);
Run Code Online (Sandbox Code Playgroud)

然而,自上一个 RAD Studio 10.3.3 Rio 版本以来,这似乎不再有效。我过去已经遇到过类似的问题,为此我可以找到解决方案: Delphi - How to correct register a graphics class since XE8?

因此,显然 Embarcadero 更改了自 10.3.3 Rio 版本以来的规则。再来一次。自此版本以来,我的图形类不再正确注册。有时是,有时不是。例如,当我第一次打开我的 IDE 时,它不是。当我尝试在设计时调试我的包时,它是。当我尝试运行一个项目时,有时是,有时不是。

有人遇到过类似的问题吗?initialization在最新的编译器版本中,有关该部分的规则是否有所更改?最后,我的代码到底有什么问题?

或者,即使经过这么多年,我仍然不明白如何在 Delphi 中正确注册图形类。在这种情况下,如果有人可以向我解释如何正确注册图形类,我将不胜感激,以便将来不再遇到此类问题。

delphi components timage registration delphi-10.3-rio

8
推荐指数
0
解决办法
384
查看次数

GetHashCode的好习惯?

对于Delphi项目(使用RAD Studio XE7构建),我想创建一个画笔字典.每个字典项包含一个TMyBrush对象作为键,描述要检索的画笔,以及GDI +画笔作为值.

TMyBrush类包含3个字段

  • 用于确定画笔类型的枚举类型(实体,渐变,......)
  • 描述画笔内容的TBrushInfo类(颜色,换行模式......)
  • 表示钳位字段的TRect

在我的字典中,我想根据他的特征检索画笔,而不是他的实例.例如,我希望通过创建本地TMyBrush实例,将其配置为黑色实体,并使用TryGetValue()函数获取匹配的GDI +值,从我的字典中获取黑色实心画笔.为此,我创建了一个TMyBrushComparer.

编写Equals()函数对我来说不是问题.但是我不知道编写GetHashCode()函数的最佳做法是什么.我倾向于写一个这样的函数:

function TMyBrushComparer.GetHashCode(const pValue: TMyBrush): Integer;
begin
    Result := BobJenkinsHash(pValue, SizeOf(TMyBrush), 0);
end;
Run Code Online (Sandbox Code Playgroud)

但是我觉得这不是一个很好的做法,这是正确的吗?那么,为我的TMyBrushComparer编写一个好的GetHashCode()函数的最佳实践是什么?

问候

delphi hash tdictionary gethashcode

6
推荐指数
1
解决办法
760
查看次数

GDI - 我可以使用新的Windows 10 Segoe UI Emoji彩色字体和DrawText吗?

我正在使用Embarcadero RAD Studio(10.2东京启动器)和Windows GDI创建一个c ++项目,通过DrawText()函数绘制文本.

我最近看到Windows 10提供了一种新的"Segoe UI Emoji"字体,它可能允许文本功能绘制彩色表情符号.我发现了几个使用Direct2D的例子,但没有一个使用纯GDI函数.

我也尝试了一个简单的代码,如下所示:

HDC hDC = ::GetDC(Handle);

std::auto_ptr<TCanvas> pCanvas(new TCanvas());
pCanvas->Handle = hDC;

pCanvas->Brush->Color = clWhite;
pCanvas->Brush->Style = bsSolid;
pCanvas->FillRect(TRect(0, 0, ClientWidth, ClientHeight));

const std::wstring text = L"Test        ";

TRect textRect(10, 10, ClientWidth - 10, ClientHeight - 10);

hFont = ::CreateFont(-40,
                      0, 
                      0,
                      0,
                      FW_DONTCARE,
                      FALSE,
                      FALSE,
                      FALSE,
                      DEFAULT_CHARSET,
                      OUT_OUTLINE_PRECIS,
                      CLIP_DEFAULT_PRECIS,
                      CLEARTYPE_QUALITY,
                      VARIABLE_PITCH,
                      L"Segoe UI Emoji");

::SelectObject(hDC, hFont);

::DrawTextW(hDC,
            text.c_str(),
            text.length(),
            &textRect,
            DT_LEFT | DT_TOP | DT_SINGLELINE);

::DeleteObject(hFont);
Run Code Online (Sandbox Code Playgroud)

输出结果在符号方面听起来不错,但它们以黑白绘制,没有颜色,如下面的屏幕截图所示: 在此输入图像描述

我找不到任何其他选项可能允许使用彩色符号而不是黑白绘制文本.有没有办法在GDI DrawText()函数中激活颜色的支持,如果是的话,怎么做?或者只有Direct2D可以绘制彩色表情符号?

于2017年10月30日编辑

由于GDI无法完成这项工作(不幸的是,正如我所想),我在这里发布了上述代码的Direct2D版本,这对我有用. …

winapi gdi colors emoji

6
推荐指数
1
解决办法
1416
查看次数

在Delphi中使用泛型类型的算术运算

我是Delphi的新手.对于我公司要求的项目,我需要将现有C++类中的一些代码翻译成Delphi.其中一些类是模板,例如:

template <class T>
struct APoint
{
    T m_X;
    T m_Y;

    virtual void Add(T value);
};

template <class T>
void APoint<T>::Add(T value)
{
    m_X += value;
    m_Y += value;
}
Run Code Online (Sandbox Code Playgroud)

我使用它,例如使用此代码

APoint<float> pt;
pt.m_X = 2.0f;
pt.m_Y = 4.0f;
pt.Add(5.0f);
Run Code Online (Sandbox Code Playgroud)

这很有效.

现在我需要为Delphi编写等效的代码.我试着写一个Delphi Generic类,基于上面的C++代码:

APoint<T> = record
  m_X: T;
  m_Y: T;

  procedure Add(value: T);
end;

procedure APoint<T>.Add(value: T);
begin
  m_X := m_X + value;
  m_Y := m_Y + value;
end;
Run Code Online (Sandbox Code Playgroud)

但是这段代码无法编译.我收到此错误:

E2015运算符不适用于此操作数类型

AFAIK这个代码应该可行,我不明白它有什么问题.那么任何人都可以向我解释:

  1. 为什么这样的代码不能在Delphi中编译?

  2. Delphi中创建一个提供Add()函数的模板类的正确(和最简单)方法是什么,尽可能接近上面的C++代码和用法?

2016年10月17日编辑

感谢所有的答复.因此,如果我理解正确,就无法创建类似c ++的样式模板,因为Delphi强加了c ++中不存在的几个约束. …

delphi generics math templates addition

5
推荐指数
3
解决办法
703
查看次数

日语文本的VCL是否会显着变慢?

我正在使用RAD Studio XE7(C++ Builder).对于我的一个项目,主窗体包含几个组件,如面板,按钮,标签,编辑框,......,其中一些组件已激活"自动调整大小"属性.到目前为止,我总是在这个界面上显示英文文本,他的开场表演是可以接受的.

我最近用日语翻译了这个界面.我注意到开放时间明显变慢了.

使用剖析器(Shiny),我测量了两者之间的差异.我注意到VCL可能会处理几个属性,比如位置和大小,直到日语界面打开时要慢10倍.性能泄漏明显,而pControl-> Width或pControl-> Margins-> Top等属性正在发生变化.我没有修改两个版本之间的任何代码行,只修改了DFM文件中的文本,没有别的.

我无法相信VCL的性能可能会像这样降低.VCL中有关日本文本表演的已知问题吗?使用VCL控件阻止此类场景的良好做法是什么?

delphi performance delphi-xe7 c++builder-xe7

5
推荐指数
0
解决办法
165
查看次数

GDI +破折号模式是否被窃听?

我正在使用Embarcadero RAD Studio XE7创建一个C++图形应用程序,我正在尝试使用GDI +和一些破折号模式属性设置循环进度动画.

这个想法非常简单:通过配置一个模式,其中短划线足够长以填充圆的圆周,并且空白部分足够长以防止两个破折号在圆上一起可见,可以显示循环进度,其中破折号偏移属性可用于显示当前进度位置.

但是,我无法通过GDI +实现目标,因为可以看到几个图形工件,我无法找到解决它们的解决方案.我很确定我使用的值是正确的,因为Direct2D处理的完全相同的绘图工作正常.

以下是显示问题的示例代码.一个圆圈用GDI +绘制,另一个圆圈用Direct2D绘制.两个圆的绘图配置完全相同.

// fill the background
TRect rect(0, 0, ClientWidth, ClientHeight);
Canvas->Brush->Color = clWhite;
Canvas->Brush->Style = bsSolid;
Canvas->FillRect(rect);

const float startY     =  100.0f;
const float penWidth   =  32.0f;
const float dashOffset = -559.0f + (float(tb1->Position) * 559.0f * 0.01f);

std::vector<float> dashPattern;
dashPattern.push_back(559.0f / penWidth);
dashPattern.push_back(559.0f / penWidth);

// --------------------------------- USING GDI+ --------------------------------------

// create a GDI+ path showing a circle
Gdiplus::GraphicsPath path;
path.StartFigure();
path.AddBezier(Gdiplus::PointF(99.99999, 11.05255 + startY),
               Gdiplus::PointF(51.31296, 11.05255 + startY),
               Gdiplus::PointF(11.05254, …
Run Code Online (Sandbox Code Playgroud)

.net drawing gdi+ artifacts

5
推荐指数
0
解决办法
366
查看次数

Direct2D - 如何绘制尽可能接近 GDI 渲染的文本

我正在使用 Embarcadero RAD Studio XE7 编译器(C++ Builder),其中我正在尝试提供的 Direct2D API。我的目的是创建提供与 GDI 完全相同的渲染的应用程序,但也可能受益于 Direct2D 提供的新功能,例如 Window 10 上的彩色表情符号。

在这种背景下,我编写了一个小型文本绘制函数,它使用 Direct2D 来完成这项工作。我还搜索了如何配置 Direct2D/DirectWrite 来绘制尽可能接近 GDI 功能的文本。

这导致了以下功能:

void DrawText_Direct2D(const std::wstring& text, const TRect& rect, TColor bgColor,
        TFont* pFont, TCanvas* pCanvas)
{
    if (!pFont || !pCanvas)
        return;

    // fill destination canvas background with provided color
    WGDIHelper::Fill(pCanvas, rect, bgColor);

    ::D2D1_RECT_F drawRect;
    drawRect.left   = rect.Left;
    drawRect.top    = rect.Top;
    drawRect.right  = rect.Right;
    drawRect.bottom = rect.Bottom;

    // get Direct2D destination canvas
    std::unique_ptr<TDirect2DCanvas> pD2DCanvas(new TDirect2DCanvas(pCanvas->Handle, rect));

    // configure Direct2D …
Run Code Online (Sandbox Code Playgroud)

directwrite

5
推荐指数
1
解决办法
2002
查看次数