On Friday, 28 February 2020 at 10:33:11 UTC, Виталий Фадеев wrote:
Thanks all !
I happy !
Check this one:
void On( T, M )( T o, M message )
{
[snip]
void main()
{
auto a = new A();
a.Send( a, WM_KEYUP );
a.Send( a, WM_KEYDOWN );
}
That does mostly work, but fails for this code:
void main()
{
Base a = new A();
a.send( a, WM_KEYUP );
}
Basically, whenever you assign a derived to a base, this solution
doesn't work, because T will be Base, not A.
I enjoyed with the previous code, so I wrote the code necessary
to handle any WM_ message:
import core.sys.windows.windows;
import std.stdio;
import std.meta;
template startsWith(string prefix) {
enum startsWith(string s) = s.length >= prefix.length &&
s[0..prefix.length] == prefix;
}
enum getMessageValue(string s) = __traits(getMember,
core.sys.windows.winuser, s);
// Get the all the WM_ messages
alias messageNames = Filter!(startsWith!"WM_",
__traits(allMembers, core.sys.windows.winuser));
alias messageValues = NoDuplicates!(staticMap!(getMessageValue,
messageNames));
class Base {
LRESULT On(UINT message, WPARAM wParam, LPARAM lParam) {
switch (message) {
foreach (msg; messageValues) {
case msg:
if (auto that =
cast(IMessageHandler!msg)this) {
return that.handle(wParam, lParam);
}
break;
}
default:
}
return 0;
}
}
interface IMessageHandler(alias msg) {
mixin("LRESULT On"~__traits(identifier, msg)~"(WPARAM wParam,
LPARAM lParam);");
alias handle = mixin("On"~__traits(identifier, msg));
}
class Button : Base, IMessageHandler!WM_KEYDOWN,
IMessageHandler!WM_SETTINGCHANGE {
LRESULT OnWM_KEYDOWN(WPARAM wParam, LPARAM lParam) {
writeln("WM_KEYDOWN");
return 0;
}
LRESULT OnWM_SETTINGCHANGE(WPARAM wParam, LPARAM lParam) {
writeln("WM_SETTINGCHANGE");
return 0;
}
}
unittest {
Base b1 = new Base();
Base b2 = new Button();
writeln("Base:");
// None of these will print anything, as Base doesn't handle
them
b1.On(WM_KEYDOWN, 0, 0);
b1.On(WM_SETTINGCHANGE, 0, 0);
b1.On(WM_DRAWITEM, 0, 0);
writeln("Button:");
b2.On(WM_KEYDOWN, 0, 0);
b2.On(WM_SETTINGCHANGE, 0, 0);
// This will print nothing, as Button doesn't handle that
message.
b2.On(WM_DRAWITEM, 0, 0);
}
--
Simen