aboutsummaryrefslogtreecommitdiff
path: root/c
AgeCommit message (Collapse)Author
2022-07-27Change WM_MENUSELECT handling.John Ankarström
This has two benefits: 1. The for loop is avoided. 2. It is shorter. The drawback is that it is a bit opaque. The order of the array elements still matter, but now it is coupled to what is declared in resource.h, a completely separate file. This makes it harder to change resource.h.
2022-07-27Fix memory bug.John Ankarström
swprintf_s excepts the NUMBER of characters, not the SIZE of the buffer. The argument is named sizeOfBuffer in the documentation, but don't let that fool you (like it did me). Interestingly enough, this bug causes a crash ONLY when compiling WITHOUT optimizations (at least on my system). The crash was introduced in 3a133c4, where I removed the `static' attribute from tszRating. I guess the optimizer moves the memory around such that the memory after the string happens to be unimportant.
2022-07-27Improve resource.h.John Ankarström
2022-07-27Fix About dialog text.John Ankarström
Because GNU windres doesn't support UTF-16, resources.rc must be saved as Latin-1.
2022-07-26Rewrite WM_MENUSELECT handling.John Ankarström
2022-07-26Use 's' instead of 'str' for as prefix for managed strings.John Ankarström
2022-07-26Remove ANSI compatibility.John Ankarström
Even though it is a fun challange in many ways, I think that, realistically, it is probably not worth the complexity. The Prolog backend isn't ANSI-compatible either.
2022-07-26Improve Win32Error, library handling code.John Ankarström
2022-07-25Move menu command processing to separate functions.John Ankarström
2022-07-25Reorganize resource IDs, message handling.John Ankarström
The resource IDs have been changed such that * the first (least significant) half byte represents the "group", * the second half byte represents the "subgroup", and * the third and fourth half bytes uniquely identify the resource within the group. Combined with the use of a few helper macros, this makes the message handling code a lot simpler.
2022-07-25Show menu item info in status bar.John Ankarström
2022-07-24Update layout on theme change.John Ankarström
2022-07-24Fix PL_get_tchars.John Ankarström
See c6cd2f1.
2022-07-24Use Query object in DataListView::ShowEpisode.John Ankarström
2022-07-24Reorganize EpisodeListView::Update.John Ankarström
2022-07-24Add const.John Ankarström
2022-07-24Use std::vector for tracking selected episodes.John Ankarström
This also fixes an off-by-one error leading to an out-of-bounds write.
2022-07-24Rename g_hFocus to g_hWndFocus.John Ankarström
2022-07-24Improve window layout.John Ankarström
This reverts much of 97f0a27. 1. It turns out not to be a good idea to resize the list view columns based on the list view window's own rectangle, as it will change depending on whether a scrollbar is visible. The problem is that resizing the columns may add a horizontal scrollbar -- which in turn may add a vertical scrollbar. 2. The WS_EX_CLIENTEDGE style does not look very good in "modern" (non-classic) themes. In 97f0a27, I tried solving this by extending the dimensions of the child windows such that their edges were hidden. However, this type of overlapping causes problems with the status bar. My new solution is to instead *reduce* the child windows' dimensions. This achieves a visual impression similar to the thicker (more well-designed) edges of the "classically themed" list view control. To make it look even better, the main window background is changed from COLOR_WINDOWFRAME (white) to COLOR_WINDOW (light gray).
2022-07-23Fix display of Unicode text.John Ankarström
Turns out that SWI-Prolog's wide string functions, which I started using in 03fe361, do not convert between narrow Prolog atoms and wide C strings, as I mistakenly thought. Instead, they work with wide Prolog atoms. In hindsight, it is not surprising.
2022-07-23Prevent scrollbar from flickering.John Ankarström
2022-07-23Improve UpdateLayout and ResizeColumns.John Ankarström
This incidentally removes the need for the variable template introduced by 21e96c6. I'm sure it will be needed at some point, though.
2022-07-22Cache GetSystemMetrics values with variable template.John Ankarström
The variable template could be generalized like this: template <auto F, auto... A> const auto cache = F(A...); and instantiated like: cache<GetSystemMetrics, SM_CXVSCROLL> It would still be limited to constant function arguments, which usually isn't a problem for GetSystemMetrics, but might be for other functions.
2022-07-22Set owner of termination message box.John Ankarström
If the main window exists, it is probably a good idea for the message box to be owned by it. Otherwise, the user may continue to interact with the main window. Of course, that could sometimes be a benefit, but it SEEMS a bit unsafe... I might change this in the future.
2022-07-22Simplify AWTEXT, AWFUN.John Ankarström
Not quite so awful anymore.
2022-07-21Simplify OnTerminate.John Ankarström
No, not "awful", AWFUN! Speaking of AWFUN, here is an alternative implementation of it: #define AWFUN(t, f) cond_fun<t, f##A, f##W> template <typename T, auto F, auto G> std::enable_if_t<std::is_same_v<T, char>, decltype(F)> cond_fun = F; template <auto F, auto G> auto cond_fun<wchar_t, F, G> = G; This implementation uses a variable template instead of a function template, but I decided against it, as (at least I think) it would instantiate useless variables that merely point to pre-existing API functions. Like, auto cond_fun__wchar_t__blablabla = MessageBoxW; auto cond_fun__char__blablabla = MessageBoxA; which is quite useless. Better to just have a constexpr function, which the compiler may inline, return the real function pointer.
2022-07-20Improve fatal error messages.John Ankarström
As the message box has no owner (because the main window may not be initialized yet), it may be unclear which application is being terminated.
2022-07-20Simplify UpdateLayout.John Ankarström
2022-07-20Simplify require, prefer.John Ankarström
2022-07-20Use GetLastError() as default for Win32Error.John Ankarström
2022-07-20Improve ANSI compatibility.John Ankarström
This improves upon 79d4fa6. Actually, ANSI compatibility may be desirable, as recent work has been done to make the A versions of Windows API functions work with UTF-8.
2022-07-20Fix ANSI compatibility.John Ankarström
It's not very useful, but it's a fun exercise.
2022-07-20Use template instead of Win32Error::twhat.John Ankarström
2022-07-20Fix timer.John Ankarström
2022-07-20Fix bug in and rename throw_nil, warn_nil.John Ankarström
In warn_nil, the return value was undefined on exception -- I think. While informative, the names throw_nil and warn_nil don't work very well in conditionals: if (warn_nil<f>(...)) g(); sounds like g should be called if f returns nil and a warning is issued. But it is actually the other way around; g is called if f is successful. if (prefer<f>(...)) g(); sounds less like that.
2022-07-20Simplify templates.John Ankarström
2022-07-19Use std::declval.John Ankarström
This is equivalent, but it may be useful to highlight that `args' does not HAVE to be declared in order to get the return type of the function call.
2022-07-19Formatting.John Ankarström
2022-07-19Check Windows API calls for errors more consistently.John Ankarström
Some of the checks are likely redundant, but the Windows API documentation rarely makes it clear WHICH errors may be returned (and under which circumstances) rather than simply WHETHER errors may be returned (under any circumstances, including those that do not apply in the given case).
2022-07-19Remove old comment.John Ankarström
2022-07-19Formatting.John Ankarström
2022-07-19Remove CreateStatusBar function.John Ankarström
2022-07-19Use static member function instead of friend function.John Ankarström
2022-07-19Add comments.John Ankarström
2022-07-19Remove EBMessageBoxA.John Ankarström
2022-07-19Use Prolog string buffer marks.John Ankarström
Speaking of unclear documentation, it is not obvious whether it is necessary for programs calling into Prolog to manually mark and release strings. I suppose that it should be, if the same logic that applies to terms apply to strings. On the other hand, the stack in which the strings are stored belongs to Prolog, and there is nothing that would prevent Prolog from cleaning up the strings when called at a later time. I am not sure. But better safe than sorry, I guess. The Mark class acts like the Frame class. The constructor and destructor are equivalent to the PL_STRINGS_MARK and PL_STRINGS_RELEASE macros. Unlike for 34c3280, I did not notice any differences in memory usage after this change. Perhaps that is because it has no effect; perhaps it is because Prolog's stack is very big.
2022-07-19Fix Prolog memory leaks.John Ankarström
Apparently foreign frames ARE needed when calling Prolog from C. The official documentation is very terse and could make this clearer. To summarize, whenever a term is created (e.g., PL_new_term_refs), its reference count is increased by one. It is garbage-collected when its reference count hits zero. But the reference count is never decreased unless (a) control returns to Prolog after executing a foreign predicate -- which does not happen in my application -- or (b) the foreign frame in which the term was created is closed. In other words, terms must be created within a foreign frame. This is achieved by initializing a Frame object before creating the term and destroying it once the term has served its purpose. The destructor for Frame does not DISCARD the frame, only CLOSE it. The former would also invalidate all data bound by the terms, which is usually undesirable.
2022-07-19Implement centered message box.John Ankarström
2022-07-18Improve Library::GetProcAddress.John Ankarström
It isn't really more safe, but it removes the need for a confusing function pointer cast, which is easy to get wrong. As far as the compiler is concerned, the result is literally the same, but it does force the caller to (indirectly, via the template parameter) cast the return value, which may be a good thing.
2022-07-18Solve compiler warnings.John Ankarström