小编bio*_*ion的帖子

应用程序桌面工具栏:Win7/8.1上ABM_SETPOS消息未预留的桌面空间

我正在修改现有的MFC应用程序以使用Win32 应用程序桌面工具栏 API,并且我有一个解决方案似乎大部分都在那里(至少对于Windows 10).但是,有三种行为 - 在三个版本的Windows上 - 我看到并且无法解释:

  1. 在Windows 7上,我的appbar定位代码根本不会移动窗口.进入/退出窗口的appar模式的样式更改正在按预期应用,但窗口保持不变,桌面工作区的大小保持不变.
  2. 在Windows 8上,appbar的位置大部分都符合预期,但最终可能会与任务栏重叠,也不会像我预期的那样在桌面上保留空间.
  3. 在Windows 10上,单个appbar按预期工作,但尝试将两个appbars固定到同一屏幕边缘只会为其中一个保留桌面空间(尽管它们都定位正确).

我的实现代码分为两个主要部分.第一个是进入/退出/修改AppBarState窗口当前的函数,它是一个枚举(包含在一个带有一些辅助函数的类中),包含每个窗口边缘的值以及禁用状态:

static constexpr DWORD AppBarStyleModifications = WS_CAPTION | WS_SIZEBOX | WS_SYSMENU;

if (!AppBarState::IsActive(eState_) && AppBarState::IsActive(eDesiredState)) {
    ModifyStyle(AppBarStyleModifications, 0, SWP_FRAMECHANGED | SWP_NOREDRAW);
    UpdateRegistration_(true);
}

if (AppBarState::IsActive(eDesiredState))
    PositionAppBar_(eDesiredState);

if (AppBarState::IsActive(eState_) && !AppBarState::IsActive(eDesiredState)) {
    UpdateRegistration_(false);
    ModifyStyle(0, AppBarStyleModifications);
}
Run Code Online (Sandbox Code Playgroud)

在此代码中,该UpdateRegistration_函数是一个简单的辅助函数,用于发送ABM_NEWABM_REMOVE消息,视情况而定.实现的主要"肉"是PositionAppBar_,它看起来像这样(有一些健全性检查和错误处理剥离空间):

APPBARDATA Data;
Data.cbSize = sizeof(APPBARDATA);
Data.hWnd = GetSafeHwnd();
Data.uCallbackMessage = APPBAR_CALLBACK;
Data.uEdge = AppBarState::ConvertToPositionCode(eDesiredState);
Data.rc = CRect(GetMonitorInfo(*this).rcMonitor).MulDiv(winx::GetDpiScalingPercent(), 100);

SHAppBarMessage(ABM_QUERYPOS, &Data); …
Run Code Online (Sandbox Code Playgroud)

mfc appbar windows-7 windows-8.1 windows-10

7
推荐指数
0
解决办法
180
查看次数

C++ 编译器内联函数局部 lambda 的效率如何?

背景

作为一种组织策略,我喜欢在复杂的函数中定义函数局部 lambda。它适用于封装多步逻辑、重复操作等(一般来说,函数适用的类型),但不会创建在使用范围之外可见的东西。这是约翰卡马克在他的关于内联代码优点的文章中阐述的风格的综合/替代品,因为它使所有东西都整齐地封装在它打算使用的函数中,同时还提供了一个(编译器识别的)名称来记录每个功能块。一个简单的、人为的例子可能看起来像这样(假设这里实际上发生了一些足够复杂的事情,值得使用这种风格):

void printSomeNumbers(void)
{
  const auto printNumber = [](auto number) {
    std::cout << number << std::endl; // Non-trivial logic (maybe formatting) would go here
  };

  printNumber(1);
  printNumber(2.0);
}
Run Code Online (Sandbox Code Playgroud)

从语义上讲,这个函数的编译形式“应该”创建一个隐式定义的函子的实例,然后operator()()为每个提供的输入调用该函子,因为这就是在 C++ 中使用 lambda 的含义。然而,在优化的构建中,as-if 规则释放了编译器来内联一些东西,这意味着实际生成的代码可能只是内联 lambda 的内容并完全跳过定义/实例化函子。关于这种内联的讨论已经出现在过去的讨论中,这里这里,以及其他地方。

在我找到的所有 lambda 内联问题和答案中,所提供的示例没有使用任何形式的lambda 捕获,而且它们在很大程度上也与将 lambda 作为参数传递给某物有关(即在std::for_each调用的上下文)。那么,我的问题是:编译器是否仍然可以内联捕获值的 lambda?更具体地说(因为我假设各种变量的生命周期在很大程度上影响了答案),编译器是否可以合理地内联一个仅在定义它的函数内部使用的 lambda,即使它捕获了一些东西(即局部变量)通过引用?

我的直觉是,内联应该是可能的,因为编译器可以完全了解所有代码和相关变量(包括它们相对于 lambda 的生命周期),但我并不乐观,我的汇编阅读技能也不是t 足够多地为我自己得到一个可靠的答案。

附加示例

以防万一我描述的特定用例不是很清楚,这里是上面 lambda 的一个修改版本,它利用了我描述的那种模式(再次,请忽略代码是人为的这一事实并且不必要地过于复杂):

void printSomeNumbers(void)
{
  std::ostringstream ss;
  const auto …
Run Code Online (Sandbox Code Playgroud)

c++ lambda compiler-optimization c++17

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

在Windows上以管理员身份运行Java应用程序

我正在用Java编写安装程序,因此需要提升权限才能访问Program Files目录.根据我在网上找到的信息,我编写了如下实现:

public static void main(String args[]) {
    if (!checkPrivileges()) { // spawn a copy w/ elevated privileges
        Runtime runtime = Runtime.getRuntime();
        try {
            Process p = runtime.exec(
                "runas /profile /user:Administrator \"java -cp . main.Main\"");
        } catch (IOException e) { ... }
    } else {
        // Run with elevated privileges
    }
}
Run Code Online (Sandbox Code Playgroud)

我用于检查权限的测试稍微修改一下,在这里找到的答案如下所示:

private static boolean checkPrivileges() {
    File testPriv = new File("C:\\Program Files\\");
    if (!testPriv.canWrite()) return false;
    File fileTest = null;
    try {
        fileTest = File.createTempFile("test", ".dll", …
Run Code Online (Sandbox Code Playgroud)

java windows uac elevated-privileges

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

std :: disjunction中的短路模板专业化

一些背景:

我正在努力整理一个模板化的类,作为模板特化的一部分,它推导出一个类型用于其中一个成员.这个数据成员需要支持通过线路流式传输,并且我试图保持系统尽可能灵活和可扩展(目标是可以通过修改专业化的一些高级元素来创建该类型的新变体逻辑没有进入实现代码的内容).一些现有的用法将此数据成员专门化为枚举,并且流代码支持将此值来回转换为32位整数以通过线路传输.

因为可以定义(隐式或显式)枚举以由不同类型支持 - 在这种情况下最危险的是64位值 - 我希望能够强制执行,如果解析的类型是枚举,它的底层类型必须是一个32位整数(更一般地说,我只需要强制它最多 32位,但是一旦更简单的情况工作,我会担心这种复杂性).

我尝试的解决方案:

type_traits提供的一些工具拼接在一起,我想出了以下内容:

#include <cstdint>
#include <type_traits>

using TestedType = /* Logic for deducing a type */;
constexpr bool nonEnumOrIntBacked =
    !std::is_enum_v<TestedType>
    || std::is_same_v<std::underlying_type_t<TestedType>, std::int32_t>;
static_assert(nonEnumOrIntBacked,
    "TestedType is an enum backed by something other than a 32-bit integer");
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试编译它时(在最新更新时使用Visual Studio 2017),我遇到了错误文本 'TestedType': only enumeration type is allowed as an argument to compiler intrinsic type trait '__underlying_type'.看到这个,我尝试了使用std :: disjunction的替代公式,我认为如果早期条件的计算结果为true,我应该对模板进行短路评估(我已经省略了std限定符以使其更具可读性):

disjunction_v<
    negation<is_enum<TestedType>>,
    is_same<underlying_type_t<TestedType>, int32_t>
>;
Run Code Online (Sandbox Code Playgroud)

我还试图捆绑的违规使用underlying_type_t …

c++ templates static-assert visual-c++ c++17

4
推荐指数
1
解决办法
178
查看次数

在C#中识别空对象

我正在进行一个方法调用,它将另外四个方法调用的结果作为参数 - 但是进行这些调用的方法可能会也可能不会为空(对不起,如果这是一个绝对无法理解的句子).这是代码,如果它使事情更清楚:

    public void Inform(Room north, Room south, Room east, Room west)
    {
        this.north = north;
        this.south = south;
        this.east = east;
        this.west = west;

        node.Inform(north.GetNode(), south.GetNode(),
                    east.GetNode(), west.GetNode());
    }
Run Code Online (Sandbox Code Playgroud)

基本上,我想知道是否有一种快速简便的方法来检查一个对象是否为null并且除了条件之外简单地将'null'传递给方法 - 我宁愿不必为null的所有16种可能变体显式编码不是空的.

编辑:为了回应混淆,我想澄清一下:大多数时候我传入方法的对象不会为空.通常,Room对象存在于北,南,东和西,如果Room存在,GetNode()方法将返回适当的对象.我想确定一个给定的Room存在是否在尝试进行方法调用时避免空引用激活.

c# xna

3
推荐指数
1
解决办法
302
查看次数

在C#中快速生成随机数

我正在创建一个程序,它创建了几个具有随机确定颜色的面板,这些面板将每20毫秒左右递增/递减一些随机常量,以创建平滑,起伏的颜色.为此,我刚刚使用Random类的Next(int)方法.对于单个实例,这非常有效 - 每次运行程序时,我都会以不同的速率变换不同的颜色.当我尝试创建多个面板时出现问题 - 大多数(如果不是全部)面板出现并且彼此表现相同,这意味着所有随机生成的数字都是相同的.我假设这是快速连续生成所有伪随机数的结果,导致所有伪随机数基于相同的种子.

有没有比使用Random类快速连续生成随机整数以确保它们不相同的更好的方法?如果没有任何方法已经内置到C#中,是否有任何直接的方法来开发伪随机数生成器(请记住,这是我第一次尝试使用C#)?

c# random

2
推荐指数
1
解决办法
2386
查看次数

在执行期间将面板添加到C#中的表单

我第一次尝试使用C#来重新创建我在Java中制作的屏幕保护程序,这种屏幕保护程序是由Java制作的,它由随机改变颜色的面板网格组成。到目前为止,我已经获得了面板工作的代码,现在我正尝试将它们添加到Form中以对布局进行原型制作。我计划确定在运行时要显示的面板数(以便16:9、4:3、16:10等都可以使屏幕保护程序看起来不错),但这是我从搜索中找到的唯一方法在Internet上向表单添加元素需要使用Visual Studio的设计工具。因此,我有几个问题:

如何以类似于Java的GridLayout设置Form的布局?

向表单添加元素需要什么代码?

我可以使用更好的方法来代替表单吗?

c# user-interface visual-studio-2010 winforms

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