4
I Use This!
Activity Not Available

News

Analyzed 4 months ago. based on code collected 7 months ago.
Posted about 7 years ago by Vidar Hasfjord
I just discovered Google Trends, and of course I had to check out how we are doing here at OWLNext. So I punched in the starting date 2009-09-02, the release date for OWLNext 6.30 — which by the way was around the time I got more heavily involved ... [More] with the project. For the ending date, I selected the present day. Here is the result: The height of the graph is relative, with numbers representing search interest relative to the highest point in the chart over the given time period. Clearly, there has been a steady decline in interest in OWLNext since 6.30. Not even the release of the C++11 and C++14 standards has had any noticable effect. How does that compare with MFC over the same period? As we all know, MFC was OWL's primary competitor, and it is still widely used. Here is the relative search term popularity over the same period as above: While MFC sees a steady decline as well, OWLNext barely registers on the graph in comparison. What about our download statistics here at SourceForge? Well, for a long time, we have had an average of 150 downloads per month of OWLMaker, our primary download file. That sounds like there is still some interest. However, I suspect most of that number are spurious downloads by robots and the like, since the numbers do not correlate much with releases. Here is the graph since July 2014, which was when OWLMaker became the primary download. Note that the peak in October last year is an anomaly due to the patch we provided for the Windows 10 Anniversary problem [discussion:a64befb5]. That patch is still by far the most popular download here, with over 7200 downloads since its release! It would be interesting to know the statistics on accesses to the code repository itself, now that the repository is the primary source for download and installation of the library. Unfortunately, SourceForge no longer provides any repository statistics, as far as I know. [Less]
Posted over 7 years ago by Vidar Hasfjord
OWLNext version 6.36, version 6.44, version 7 (trunk), and Owlet now support the latest C++ compiler in Visual Studio 2017 RC. OWLMaker has been updated as well, and will now allow you to use the Visual Studio 2017 toolset to build OWLNext 6.36.1 ... [More] , 6.44.1 and later. Note that, due to changes in the new setup engine for Visual Studio, OWLMaker cannot yet locate the Visual Studio 2017 toolset, so you will have to specify the path manually. Note that the path should point to the VC folder within the product folder. For example, "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC". [Less]
Posted over 7 years ago by Vidar Hasfjord
As part of the Windows message dispatch overhaul for 64-bit compatibility, OWLNext 6.40 introduced a new implementation of the OWL response tables (see Windows Message Dispatch). Like the old implementation, the new solution ensures that the ... [More] signature of an event handler matches the expected signature defined by the message. In fact, the type-safety is now much improved over the brittle non-standard-conforming solution in the Borland implementation. However, the error message given on a signature mismatch is less helpful than in previous versions. Poor error messages On an event handler signature mismatch, Visual C++ just points to the response table as a whole — not the specific line of the mismatching entry — and the error message just says: error C2440: 'initializing': cannot convert from 'overloaded-function' to 'owl::TDispatchFunction' For Visual Studio 2015, the IntelliSense feature in the code editor isn't even able to detect the mismatch, so you will not see any helpful red squiggles to point you to the source of the error. The Clang-based Embarcadero compilers in C++Builder/RAD Studio are just as unhelpful: error E1538: address of overloaded function 'Decode' does not match required type 'long long (void *, unsigned long long, long long)' This error message is misleading the user, since the signature of the underlying Decode function isn't the issue. In addition, a lot of additional messages ("hints") are given about the definition of the macros, thus overwhelming the user with irrelevant implementation details. The classic BCC32 compiler in Embarcadero C++Builder/RAD Studio is the only supported compiler that gives a descriptive error message: error E2034: Cannot convert 'void (TClockWindow::*) (int)' to 'void (TClockWindow::*) (unsigned int)' in function long TDispatch <275>:: Decode (void *, unsigned int, long) This error message actually describes the problem accurately: a mismatch in the signature of the EvTimer event handler. Unfortunately, the error message points to the "owl/dispatch.h" header, not the response table in the user's code. The poor error messages leave the user to manually identify the erroneous response table entry — e.g. by commenting out entries until only the erroneous one remains. If the correct signature for the corresponding event handler is not clear, the user may have to look up the signature manually. Since the documentation of the response table macros is lacking, the user may have to look up the documentation for the underlying definition of the TDispatch specialisation for the particular message, or look at the actual source code. This exposes the user to the implementation details of the message dispatch machinery. Since the implementation uses macros, templates and meta-programming, users may find this daunting. Why are the error messages so poor? Curiously, the modern compilers give poor error messages for signature mismatches, while the old BCC32 compiler gives a pretty good error message. Why is that? The reason may be that the modern compilers are more compliant to the C++ standard, especially the complex rules regarding instantiation of a template, and in particular, whether an instantiation failure is considered a hard compilation error or just causes a rejection of that template in the overload candidate set. In the new response table implementation, the initialisation of a table entry involves the instantiation of a Decode function template for the given message. It may unfold as follows: When it comes to instantiate the Decode function template, the compiler tries to pass the given event handler (member function pointer) as a template argument. If there is a mismatch in the type of the argument, i.e. the event handler signature is wrong, then the template instantiation fails. However, this in itself is not considered an error according to the C++ standard. A standard-compliant compiler will just silently reject the template and look for alternative overloads (this is the SFINAE rule — substitution failure is not an error). Since Decode has no overloads, there is no alternative in this case, meaning the overload candidate set is empty, and the compiler reports an error. Confusingly, the poor error messages then refer to the subsequent use of the failed template instantiation, and the reason for failing to instantiate the template in the first place (i.e. the signature mismatch in the template argument) is not mentioned at all. This is probably why the Visual C++ error message points to the response table as a whole and not the erroneous entry. I ran a simplified test case at Compiler Explorer using the most recent versions of Clang and GCC. Clang 3.9's error message was unhelpful: "note: candidate template ignored: invalid explicitly-specified argument for template parameter". However, GCC 5 does diagnose the reason for the instatiation failure: "note: template argument deduction/substitution failed: error: could not convert template argument 'bar' to 'void (*)()'". Improving the error messages While it is possible that future versions of the Microsoft and Embarcadero compilers will improve their error messages (similar to GCC 5), it would be nice to get better diagnostics with the current compilers. A solution is to reintroduce signature checker functions, as used in the Borland implementation of the response tables. However, unlike the brittle Borland solution, we do not want to restate the correct signature. Luckily, with the template solution, we have the tools to calculate it: template <class T, TMsgId MsgId, template <TMsgId> class D> void CheckSignature(typename D<MsgId>::template THandler<T>) {} THandler is defined within the dispatch template specialisation as follows: template <> struct TDispatch<WM_TIMER> : TDispatchBase<WM_TIMER, void> { template <class F> static auto Encode(F sendMessage, HWND wnd, uint id) -> THandlerResult {return FORWARD_WM_TIMER(wnd, id, sendMessage);} template <class T> using THandler = TMemFunHandlerSig<T, decltype(Encode<TSendMessage>)>; //... }; Here, TMemFunHandlerSig is a meta-function that calculates the correct signature based on the signature of the Encode functions. It does so by stripping off the two first parameters for Encode, which are always sendMessage (a callable object) and wnd (the handle of the window). In this particular example, this leaves us with uint id as the only parameter left. The resulting event handler signature for WM_TIMER thus becomes void (T::*)(uint id), since THandlerResult in this case is void. Now we have to insert a call to CheckSignature within every response table entry. We can do this by using a comma expression: #define OWL_RESPONSE_TABLE_ENTRY(msgId, notificationCode, sourceId, dispatcher, signatureCheck)\ {msgId, notificationCode, sourceId, (signatureCheck, dispatcher)} This macro takes the signature check as a parameter, so that it can be customised to the particular message type. For example, response table entries for notification messages use a slightly different overload of CheckSignature that looks up the THandler signature within the TNotificationDispatch template spesialisation for the notification ID (e.g. EN_CLICKED), which in turn is defined within the dispatch template for the carrier message (e.g. WM_NOTIFY). This solution has now been implemented in Owlet, and a simplified version has been implemented on the trunk (version 7) and in OWLNext 6.44. However, the solution is only enabled for the Microsoft compiler and the Clang-based Embarcadero compilers. Unfortunately, BCC32 is not able to compile it, but as described above, the error messages produced by this compiler is pretty helpful anyway. [Less]
Posted over 7 years ago by Vidar Hasfjord
As part of the Windows message dispatch overhaul for 64-bit compatibility, OWLNext 6.40 introduced a new implementation of the OWL response tables (see Windows Message Dispatch). Like the old implementation, the new solution ensures that the ... [More] signature of an event handler matches the expected signature defined by the message. In fact, the type-safety is now much improved over the brittle non-standard-conforming solution in the Borland implementation. However, the error message given on a signature mismatch is less helpful than in previous versions. Poor error messages On an event handler signature mismatch, Visual C++ just points to the response table table as a whole — not the specific line of the mismatching entry — and the error message just says: error C2440: 'initializing': cannot convert from 'overloaded-function' to 'owl::TDispatchFunction' For Visual Studio 2015, the IntelliSense feature in the code editor isn't even able to detect the mismatch, so you will not see any helpful red squiggles to point you to the source of the error. The Clang-based Embarcadero compilers in C++Builder/RAD Studio are just as unhelpful: error E1538: address of overloaded function 'Decode' does not match required type 'long long (void *, unsigned long long, long long)' This error message is misleading the user, since the signature of the underlying Decode function isn't the issue. In addition, a lot of additional messages ("hints") are given about the definition of the macros, thus overwhelming the user with irrelevant implementation details. The classic BCC32 compiler in Embarcadero C++Builder/RAD Studio is the only supported compiler that gives a descriptive error message: error E2034: Cannot convert 'void (TClockWindow::*) (int)' to 'void (TClockWindow::*) (unsigned int)' in function long TDispatch <275>:: Decode (void *, unsigned int, long) This error message actually describes the problem accurately: a mismatch in the signature of the EvTimer event handler. Unfortunately, the error message points to the "owl/dispatch.h" header, not the response table in the user's code. The poor error messages leave the user to manually identify the erroneous response table entry — e.g. by commenting out entries until only the erroneous one remains. If the correct signature for the corresponding event handler is not clear, the user may have to look up the signature manually. Since the documentation of the response table macros is lacking, the user may have to look up the documentation for the underlying definition of the TDispatch specialisation for the particular message, or look at the actual source code. This exposes the user to the implementation details of the message dispatch machinery. Since the implementation uses macros, templates and meta-programming, users may find this daunting. Why are the error messages so poor? Curiously, the modern compilers give poor error messages for signature mismatches, while the old BCC32 compiler gives a pretty good error message. Why is that? The reason may be that the modern compilers are more compliant to the C++ standard, especially the complex rules regarding instantiation of a template, and in particular, whether an instantiation failure is considered a hard compilation error or just causes a rejection of that template in the overload candidate set. In the new response table implementation, the initialisation of a table entry involves the instantiation of a Decode function template for the given message. It may unfold as follows: When it comes to instantiate the Decode function template, the compiler tries to pass the given event handler (member function pointer) as a template argument. If there is a mismatch in the type of the argument, i.e. the event handler signature is wrong, then the template instantiation fails. However, this in itself is not considered an error according to the C++ standard. A standard-compliant compiler will just silently reject the template and look for alternative overloads (this is the SFINAE rule — substitution failure is not an error). Since Decode has no overloads, there is no alternative in this case, meaning the overload candidate set is empty, and the compiler reports an error. Confusingly, the poor error messages then refer to the subsequent use of the failed template instantiation, and the reason for failing to instantiate the template in the first place (i.e. the signature mismatch in the template argument) is not mentioned at all. This is probably why the Visual C++ error message points to the response table as a whole and not the erroneous entry. I ran a simplified test case at Compiler Explorer using the most recent versions of Clang and GCC. Clang 3.9's error message was unhelpful: "note: candidate template ignored: invalid explicitly-specified argument for template parameter". However, GCC 5 does diagnose the reason for the instatiation failure: "note: template argument deduction/substitution failed: error: could not convert template argument 'bar' to 'void (*)()'". Improving the error messages While it is possible that future versions of the Microsoft and Embarcadero compilers will improve their error messages (similar to GCC 5), it would be nice to get better diagnostics with the current compilers. A solution is to reintroduce signature checker functions, as used in the Borland implementation of the response tables. However, unlike the brittle Borland solution, we do not want to restate the correct signature. Luckily, with the template solution, we have the tools to calculate it: template <class T, TMsgId MsgId, template <TMsgId> class D> void CheckSignature(typename D<MsgId>::template THandler<T>) {} THandler is defined within the dispatch template specialisation as follows: template <> struct TDispatch<WM_TIMER> : TDispatchBase<WM_TIMER, void> { template <class F> static auto Encode(F sendMessage, HWND wnd, uint id) -> THandlerResult {return FORWARD_WM_TIMER(wnd, id, sendMessage);} template <class T> using THandler = TMemFunHandlerSig<T, decltype(Encode<TSendMessage>)>; //... }; Here, TMemFunHandlerSig is a meta-function that calculates the correct signature based on the signature of the Encode functions. It does so by stripping off the two first parameters for Encode, which are always sendMessage (a callable object) and wnd (the handle of the window). In this particular example, this leaves us with uint id as the only parameter left. The resulting event handler signature for WM_TIMER thus becomes void (T::*)(uint id), since THandlerResult in this case is void. Now we have to insert a call to CheckSignature within every response table entry. We can do this by using a comma expression: #define OWL_RESPONSE_TABLE_ENTRY(msgId, notificationCode, sourceId, dispatcher, signatureCheck)\ {msgId, notificationCode, sourceId, (signatureCheck, dispatcher)} This macro takes the signature check as a parameter, so that it can be customised to the particular message type. For example, response table entries for notification messages use a slightly different overload of CheckSignature that looks up the THandler signature within the TNotificationDispatch template spesialisation for the notification ID (e.g. EN_CLICKED), which in turn is defined within the dispatch template for the carrier message (e.g. WM_NOTIFY). This solution has now been implemented in Owlet, and a simplified version has been implemented on the trunk (version 7) and in OWLNext 6.44. However, the solution is only enabled for the Microsoft compiler and the Clang-based Embarcadero compilers. Unfortunately, BCC32 is not able to compile it, but as described above, the error messages produced by this compiler is pretty helpful anyway. [Less]
Posted over 7 years ago by Vidar Hasfjord
With the new implementation of Windows Message Dispatch introduced in OWLNext 6.40, the error messages given by the Microsoft compiler and the new Clang-based Embarcadero compilers on an event handler signature mismatch became less helpful than in ... [More] previous versions. Version 6.44 implements explicit signature checking which provides much better error messages, and which works well with IntelliSense in Visual Studio, by underlining the particular response table entry causing the error. OWLNext 6.44 also includes bug-fixes for OCFNext, as well as all the bug-fixes applied in 6.36. Changes Source Installation Guide Please test and give feedback in our forums. [Less]
Posted over 7 years ago by Vidar Hasfjord
With the new implementation of Windows Message Dispatch introduced in OWLNext 6.40, the error messages given by the Microsoft compiler and the new Clang-based Embarcadero compilers on an event handler signature mismatch became less helpful than in ... [More] previous versions. Version 6.44 implements explicit signature checking which provides much better error messages, and which works well with IntelliSense in Visual Studio, by underlining the particular response table entry causing the error. OWLNext 6.44 also includes bug-fixes for OCFNext, as well as all the bug-fixes applied in 6.36. Changes Source Installation Guide Please test and give feedback in our forums. [Less]
Posted over 7 years ago by Vidar Hasfjord
This release fixes many regressions related to our string overhaul in 6.32, as well as a few other issues. For all the details, see bugs/milestone/6.36. These fixes will be incorporated into the upcoming 6.44 release as well. OWLNext 6.36.0 ... [More] (changes | code) Installation Guide With this release, I will stop supporting the 6.3X-series, i.e. unless someone else volunteer to continue support, I expect 6.36 to be the last version with support for Borland C++. Note that 6.36 is only meant as a stepping stone for users upgrading from OWL to OWLNext, to ease the migration to the latest version and modern development tools. Note that the latest version, currently OWLNext 6.43, has many additional bug-fixes and features. If you still run OWLNext applications on an earlier version, I recommend that you upgrade. [Less]
Posted over 7 years ago by Vidar Hasfjord
This release fixes many regressions related to our string overhaul in 6.32, as well as a few other issues. For all the details, see bugs/milestone/6.36. These fixes will be incorporated into the upcoming 6.44 release as well. OWLNext 6.36.0 ... [More] (changes | code) Installation Guide With this release, I will stop supporting the 6.3X-series, i.e. unless someone else volunteers to continue support, I expect 6.36 to be the last version with support for Borland C++. Note that 6.36 is only meant as a stepping stone for users upgrading from OWL to OWLNext, to ease the migration to the latest version and modern development tools. Note that the latest version, currently OWLNext 6.43, has many additional bug-fixes and features. If you still run OWLNext applications on an earlier version, I recommend that you upgrade. [Less]
Posted over 7 years ago by Vidar Hasfjord
This release commits a series of bug fixes that have been made on the release branches. For details, see the update log and milestone report for each version. OWLNext 6.43.1 (changes | code) OWLNext 6.35.1 (changes | code) Installation Guide
Posted almost 8 years ago by Vidar Hasfjord
The start-up failure for Unicode applications, after the Anniversary Update for Windows 10, has been fixed in this release. See [bugs:#342]. OWLNext 6.43.0 (changes | code) OWLNext 6.35.0 (changes | code) Installation Guide