我正在为第三方MFC应用程序编写Win32插件DLL.DLL需要显示模式对话框.当我使用DialogBox()或其他普通的Win32 API(例如我试图编写自己的模态循环)时,主应用程序的窗口不会重绘所有元素:它重绘标准元素,但不重绘客户区.无模式对话框显示得很好.

我怀疑这是因为MFC在Win32意义上没有真正的模态对话框.它只能有一个消息循环和一个单独的循环来DialogBox()破坏其精密的机械.这是一篇CodeProject文章,解释了这一点.但是CodeProject的这篇文章已经有9年了,所以也许从那时起事情发生了变化.有人可以对此有所了解吗?该应用程序使用MFC 8(即mfc80.dll).
更新.这是原始问题的链接; 它可能包含一些额外的信息.
更新2.感谢大家; 我非常感谢所有的建议,它肯定有助于我全面了解事物如何融合在一起.我要探索的第一条路径是使用原生MFC"模态"对话框.(因为我用Python做了所有这些,我将使用Python绑定用于MFC pywin32).这需要一些时间; 当它准备好了,我会用结果更新帖子.
我有以下C代码:
unsigned int a;
unsigned char b, c;
void test(void) {
if (a < b)
return;
if (a < (b ? b : c))
return;
}
Run Code Online (Sandbox Code Playgroud)
当我编译它(使用Microsoft cl,来自MS SDK 7,-W3警告级别)时,第二个比较会发出警告:C4018,签名/无符号不匹配.第一次比较没有发出警告.
我已经在条件运算符上检查了MS文档,并且他们说如果两个操作数是相同的类型,结果将是相同的类型,所以它应该作为第一个比较.我错过了什么吗?
UPD:测试gcc -Wall -Wextra -pedantic并且没有任何警告.
这是早期问题的完全重写版本; 我认为第一个版本省略了重要的细节; 这个提供了所有的背景.
我有一些C++ API的标题.API声明了一些这样的类:
class Foo
{
public:
inline void Bar(void);
/* more inlines */
private:
inline Foo();
/* maybe more inline constructors */
}
Run Code Online (Sandbox Code Playgroud)
即没有成员,除了构造函数之外,所有函数都是内联的和公共的.构造函数是私有的,因此,据我所知,C++,我无法真正称它们为.要创建这些对象,我应该使用auto_ptrs:
class FooAutoPtr : public std::auto_ptr<Foo>
{
public:
inline FooAutoPtr();
/* one for each Foo constructors */
}
Run Code Online (Sandbox Code Playgroud)
API还有第二组函数,如下所示:
void Foo_Bar(void *self);
Foo* Foo_Constructor();
Run Code Online (Sandbox Code Playgroud)
我们称它们为核心函数,因为它们是实际从主机应用程序导出的符号.不是C++类.
核心函数具有C链接(即它们声明为extern "C"),但它们被声明为获取和返回C++类型(例如,它们可以引用:)Foo &foo.最后,头部包含C++类的内联函数的实现.所有这些功能都是一样的:它们调用核心功能.例如,FooAutoPtr构造函数是这样的:
inline FooAutoPtr::FooAutoPtr()
{
reset(Foo_Constructor());
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,代码接收一些对象,该对象应该是Foo来自主机应用程序的指针,并将auto_ptrGizmo 更改为指向此对象.但对于开发人员来说,它看起来好像是一个真正的指针Foo.呼叫Foo::Bar() …
我正在编写一个 Python 模块,它只有大约 20 个有趣的类型和全局方法,但有大量常量和异常(大约 70 个用于语言环境的常量、60 个用于编码的常量、20 个格式化属性、超过 200 个异常,等等)。结果help(),该模块生成了大约 16,000 行文本,并且散布着对每个异常几乎相同的描述。这些常数的要求并不高,但导航它们仍然很困难。
组织这样一个模块的Pythonic方式是什么?就保留原样并依赖其他文档吗?将常量移动到单独的字典中?进入子模块?在适当的情况下将它们添加为类级常量?
请注意,这是一个 C 扩展,因此我无法在此处轻松添加真正的子模块。我听说这并sys.modules没有真正检查对象是否有模块,因此可以在那里添加字典;这样我就可以创建mymodule.locales、mymodule.encoding和 ,并在导入模块时mymodule.exceptions将它们添加到其中。sys.modules这是个好主意还是太黑客了?
文档GetFullPathName()说明为了使用长度超过MAX_PATH(260个字符)的路径,我需要在文件命名空间前缀前加上:\\?\.但是,文件名的一般文档说明此前缀不能与相对路径一起使用,因此相对路径的长度始终限制为260个字符.这是否意味着没有办法使用GetFullPathName()相对路径长于MAX_PATH?(如果是这样,那么我的理解是该函数不支持长路径,除非传递的路径已经是完整路径.)
有一个由gsscoder编写的C#的CommandLine解析器库(它有自己的SO标签,我正在添加它).它以getopt样式解析命令行选项,即:
myprogram --foo --bar=baz abc def ghi
Run Code Online (Sandbox Code Playgroud)
它还可以具有所谓的"未绑定"参数,即不受选项约束的独立位置参数; 在以上这些的例子是abc,def,和ghi.不幸的是,文档只提到"解析器有办法处理这些",但没有给出一个例子.而且我的C#并不那么尖锐,所以我被扫描的源代码量吓到了.
有人可以举一个解析后如何访问这些未绑定参数的例子吗?
我有一个头文件,应该是一个组合的C++和C API.C部分被包装extern "C",但声明本身看起来与C不同; 例如:
foo::Bar& Foo_Baz_GetBarOfQux(void *_self, const foo::Qux &qux);
Run Code Online (Sandbox Code Playgroud)
有没有办法从普通C实际使用它?我显然不能使用这个标题,但也许我可以以某种方式重新声明它:
/* type? */ Foo_Baz_GetBarOfQux(void*, const /* type? */);
Run Code Online (Sandbox Code Playgroud)
令我困惑的是如何声明这些引用的类型(如果可能的话).
PS我知道我可以编写自己的C包装器:我将类声明为不透明结构:
typedef struct foo_bar foo_bar_t;
typedef struct foo_baz foo_baz_t;
typedef struct foo_qux foo_qux_t;
Run Code Online (Sandbox Code Playgroud)
然后编写一个包含上述函数的类C函数:
extern "C"
foo_bar_t*
foo_baz_get_bar_of_qux(
foo_baz_t* baz,
foo_qux_t* qux)
{
return (foo_bar_t*) Foo_Baz_GetBarOfQux(baz, *(foo::Qux*)qux);
}
Run Code Online (Sandbox Code Playgroud)
但我想知道我是否可以Foo_Baz_GetBarOfQux()直接使用原版.
我可以定义指向视图的外键(在 SQLite 3.8.2 中)吗?
我的情况是:我有一个项目清单;每个项目都有特定的类型;每种类型都有一个插槽(属性)列表:
create table "type" ("type id" integer primary key);
create table "slot" (
"slot id" integer primary key,
"type id" integer not null
references "type" ("type id") on update cascade on delete cascade);
create table "item" (
"item id" integer primary key
"type id" integer not null
references "type" ("type id") on update cascade on delete cascade);
Run Code Online (Sandbox Code Playgroud)
现在我想写一个更改日志:项目A,插槽B,值X:
create table "change" (
"item id" integer not null
references "item" ("item …Run Code Online (Sandbox Code Playgroud) 为了调试一个复杂的 XSLT 转换,我将它分成几个部分:首先我构建%.1.xml,然后我用它来构建%.2.xml,最后我构建%.3.xml. 一切正常,但是如果我要求 Make 构建最后一个,那么 Make 总是会删除中间的%.1.xml和%.2.xml,而我宁愿保留它们。我试图将所有.xml文件标记为.PRECIOUS:
.PRECIOUS: %.xml
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用。(我也尝试使用%.1.xmland %.2.xml,但这也不起作用。然后我尝试以.SECONDARY相同的方式将它们标记为相同的负面结果。它不删除中间文件的唯一方法是当文件已经存在;在这种情况下,它只重建它们。但如果文件不存在,它总是删除它们。
我错过了什么?
GNU 制作 4.1。
更新: Makefile,>>代表TAB:
sample-%.1.xml: sample-%.0.xml job.1.xslt job.xslt
>> xsltproc $(filter %.1.xslt,$^) $(filter %.xml,$^) > $@
sample-%.2.xml: sample-%.1.xml job.2.xslt job.xslt
>> xsltproc $(filter %.2.xslt,$^) $(filter %.xml,$^) > $@
sample-%.3.xml: sample-%.2.xml job.3.xslt job.xslt
>> xsltproc $(filter %.3.xslt,$^) $(filter %.xml,$^) > $@
.SECONDARY: %.xml # …Run Code Online (Sandbox Code Playgroud) c ×3
c++ ×2
reference ×2
winapi ×2
constants ×1
exception ×1
foreign-keys ×1
gnu-make ×1
makefile ×1
mfc ×1
modal-dialog ×1
organization ×1
python ×1
sqlite ×1
visual-c++ ×1