这与Assigning events to a VCL control created dynamically at runtime有关。
我使用上面列出的/参考文章解决了一些代码存在的问题。感谢您提供该示例。我发现它非常有用,并实现了它提供的“替代”方式,因为我无法使第一种方式起作用。
我正在使用Embarcadero的C ++ Builder10.x。我刚刚更新到C ++ Builder 10.3。现在,此新更新引发警告:
[bcc32c警告] LogitToMemo.cpp(196):指针到函数和指针到对象之间的隐式转换是Microsoft扩展
它抛出的行是:
Method.Code = &LogLevelComboBoxOnChange;
我不确定如何“修复”此问题。
该代码支持备忘录字段的日志记录功能,其中日志记录备忘录的页面具有TComboBox
,用于选择日志记录级别/详细程度。
TComboBox
在记录功能的外部,就像在用户窗体上一样。我希望TComboBox::OnChange
事件调用我的LogLevelComboBoxOnChange
函数,该函数根据所选的TComboBox
项目/条目来调整日志记录级别。
与此相关的支持代码。
函数声明-TComboBox::OnChange
事件函数
void __fastcall LogLevelComboBoxOnChange(void *pThis, TObject *Sender);
功能声明-在提供要登录的TMemo
字段和TComboBox
的地方启动日志记录
int LogStartWithComboBox(TMemo *LogIt_MemoField, TComboBox *AppLogLevelComboBox, int iThreshold, AnsiString &asFieldTitles);
这是将OnChange
函数分配给用户日志表单上的TComboBox
对象的函数。
int LogStartWithComboBox(TMemo *LogIt_MemoField, TComboBox *AppLogLevelComboBox, int iThreshold, AnsiString &asFieldTitles)
{
static TMethod Method;
//
// Set-Up CombBox and OnChange Event
// - Save ComboBox pointer
// - Assign List of Log Levels
// - Assign/Set-Up OnChange Function
//
LogLevelComboBox = AppLogLevelComboBox;
AppLogLevelComboBox->Items->Text =
"Off\n"
"All Messages\n"
"Verbose\n"
"Trace\n"
"Informational\n"
"Warning\n"
"Error\n"
"Severe\n"
"Fatal";
AppLogLevelComboBox->ItemIndex = iThreshold + 1;
//
// Set-Up - On Change Function for "external" Log Level Combo-Box
//
Method.Data = NULL; // passed to the pThis parameter, can be whatever you want
//
// The Following line generates the warning
// [bcc32c Warning] LogitToMemo.cpp(196): implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension
//
Method.Code = &LogLevelComboBoxOnChange;
LogLevelComboBox->OnChange = reinterpret_cast<TNotifyEvent&>(Method);
return 0;
}
答案 0 :(得分:0)
您正在使用C ++ Builder基于CLang的C ++编译器。您看到的“隐式转换”警告是一个CLang问题,该问题在过去几年中出现在使用CLang的多个工具链中,而不仅仅是在C ++ Builder中。此问题不会影响C ++ Builder的“经典”(非CLang)编译器。
&LogLevelComboBoxOnChange
创建一个指向函数的指针,除非将Clang放入Clang中,否则CLang不希望将其隐式转换为void*
(这是TMethod::Code
字段的声明)。 Microsoft兼容模式。
可能的解决方案之一是:
显式类型化指针:
(更新:显然是doesn't like static_cast
ing指向void*
的函数指针!)
Method.Code = static_cast
Method.Code = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(&LogLevelComboBoxOnChange));
在CLang编译器设置中启用-Wmicrosoft-cast
标志。
通过在分配给#pragma
的周围使用Method.Code
语句来禁用代码中的警告:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmicrosoft-cast"
Method.Code = &LogLevelComboBoxOnChange;
#pragma clang diagnostic pop
使用union
(不过,我敢肯定,有些人会说这可能违反了严格的别名规则,但是如果可行的话……):
union {
void (__fastcall *func)(void*, TObject*);
void *ptr;
} u;
u.func = &LogLevelComboBoxOnChange;
Method.Code = u.ptr;