Radio buttons not selecting in old program - c

I wrote a large complex C program around 20(!) years go. As far as I can recall it worked fine at the time in all respects - it was probably running on windows 95.
Now I need to use it again. Unfortunately the radio buttons in it do not appear to work properly any more (the ordinary push buttons are all behaving correctly). As I click on the radio buttons, I get some feedback that windows is acknowledging my click in as much as I see a dotted line appear around the button's text and the circle of the button goes grey for as long as my finger is on the button, but when I take my finger off I see that the selected button has not changed.
My suspicion is that I was perhaps getting away with some bad practice at the time which worked with windows 95 but no longer works on newer versions of windows, but I'm struggling work out what I did wrong. Any ideas?
EDIT: Its difficult to extract the relevant code because the message handling in this program was a tangled nightmare. Many buttons were created programatically at runtime and there were different message loops working when the program was in different modes of operation. The program was a customisable environment for running certain types of experiment. It even had its own built-in interpreted language! So I'm not expecting an answer like "you should have a comma instead of a semicolon at line 47", but perhaps something more like "I observed similar symptoms once in my program and it turned out to be ..... " .. or perhaps "the fact that the dotted rectangle is appearing means that process AAA has happened, but maybe step BBB has gone wrong".
EDIT: I've managed to extract some key code which my contain an error...
char *process_messages_one_at_a_time()
{
MSG msg;
int temp;
temp = PeekMessage(&msg,winh,0,0,PM_NOREMOVE);
if (temp)
{
GetMessage (&msg, NULL, 0, 0);
if (msg.message == WM_LBUTTONUP)
{
mouse_just_released_somewhere = TRUE;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
if (button_command_waiting)
{
button_command_waiting = FALSE;
return (button_command_string);
}
else
{
return (NULL);
}
}

There are two simple things to check when using radio buttons. First is to make sure that each has the BS_AUTORADIOBUTTON property set. The second is to make sure that the first button in the tab order and the next control after the set of buttons (typically a group box) have the WS_GROUP property set, while the other buttons have it clear.

A few suggestions:
I'd try to use spy++ to monitor the messages in that dialog box, particularly to and from the radiobutton controls. I wonder if you'll see a BM_SETCHECK that your program is sending (ie, somewhere you're unchecking the button programatically).
Any chance your code ever checks the Windows version number? I've been burned a few times with an == where I should have used a >= to ensure version checking compatibility.
Do you sub-class any controls? I don't remember, but it seems to me there were a few ways sub-classing could go wrong (and the effects weren't immediately noticeable until newer versions of Windows rolled in).
Owner-drawing the control? It's really easy to for the owner-draw to not work with newer Windows GUI styles.
Working with old code like that, the memories come back to me in bits and pieces, rather than a flood, so it usually takes some time before it dawns on me what I was doing back then.

If you just want to get the program running to use it, might I suggest "compatibility mode".
http://www.howtogeek.com/howto/windows-vista/using-windows-vista-compatibility-mode/
However, if you have a larger, expected useful life of the software, you might want to consider rewriting it. Rewriting it is not anywhere near the complexity or work of the initial write because of a few factors:
Developing the requirements of a program is a substantial part of the required work in making a software package (the requirements are already done)
A lot of the code is already written and only parts may need to be slightly refactored in order to be updated
New library components may be more stable alternatives to parts of the existing codebase
You'll learn how to write current applications with current library facilities
You'll have an opportunity to comment or just generally refactor and cleanup the code (thus making it more maintainable for the anticipated, extended life)
The codebase will be more maintainable/compatible going forward for additional changes in both requirements and operating systems (both because it's updated and because you've had the opportunity to re-understand the entire codebase)
Hope that helps...

Related

Problems detecting key combinations in WinForms app under Mono on Mac

I'm trying to get a .net 2 Windows.Forms application running on the Mac using Mono. The application has key combination short cuts for all functions, which have pre-defined defaults and can be reconfigured by the user. The Form KeyDown event handler looks up the action to be performed.
My problem is relating the Modifiers and KeyCode to the actual keys pressed. I don't mind if some mapping needs to be added for the Mac, but I need at least 3 modifier keys. However of the 4 modifiers on the Mac, few seem to produce obvious results. I get:
Shift - works as expected
Ctrl - reports a different KeyCode, but with correct modifier (eg Ctrl+N has Modifiers = Control and KeyCode 14 = "RButton, Clear").
Alt - reports some other key, unmodified (eg Alt+R gives KeyCode = 168 = "BrowserRefresh")
Cmd - reports as Alt with expected KeyCode (eg Cmd+N appears as Alt-N)
I presume that the Cmd key would normally be used where Ctrl is used on Windows. Can anyone advise which of the three Mac keys I should be trying to use? And most importantly how to parse the KeyEventArgs to consistently report a base key plus three optional modifiers?
Mono is the latest version (as of a week or two ago), and it's a MacBook Air, OS X 10.8.1 if that makes any difference.
I get the same issues. Try using IRC and asking at irc.gnome.org on rooms Mono and MonoMac. Very helpful folks.
Apparently with MonoMac, which lets you build a native UI in Interface Builder and helps stub out your backend C# code to talk to it (that is, MonoMac is Mono talking to native Mac, not Mono running on a Mac; the second is just plain Mono), Windows.Forms support has dropped to the wayside -- I was told that Windows.Forms is essentially "dead" on the Mac, and the quiet bugzilla page seems to support that. It really is quite buggy. I ran into SelectionBackColor not working in RichTextBox right off the bat, then menu accelerators not working reliably. Windows.Forms on Mac is alpha to beta quality, I think.
That said, for what's essentially a labor of love, a surprising amount of Windows.Forms works well, but I wouldn't use it for a polished app. Good luck.
EDIT: I realize the OP wasn't specifically talking about menuitems, but here's a bug report about accelerators and menu items not working so well, just to speak to related bugginess.
[Mono-bugs] [Bug 75996][Maj] New - menuitem event not triggered by Shortcut
Windows.Forms on Mono is so close to working, it's tempting to think it's going to support what you need to get done, but, imo, to consider it solid enough for use beyond making quick utilities would be a mistake.
In case it's useful to anyone, this is where I ended up:
I eventually managed to hack my way around this particular 'feature' by creating a new KeyData value to replace the one provided by the event (this code running only if it's a Mac).
I swapped round some of the modifiers to make it more consistent with windows (ie if Cmd was pressed, and reported as Alt by Mono I changed that to Ctrl). I also filtered out ctrl+A to ctrl+Z which return KeyCodes 0 to 25 (not 65 to 90) and replaced these with their normal values.
Fortunately my code only wanted the KeyData. It wouldn't be possible to create a new KeyEventArgs using the updated data, since Mono checks the current keyboard state and sets modifier flags for any pressed modifier keys, in addition to any modifiers passed to the KeyEventArgs constructor.
BUT - as ruffin commented Mono on the Mac is very flaky. We've parked this work for the moment as it's taking quite a bit of time to work around all the problems. So far we've managed to find a solution for each item we've looked at, and may well come back to this - but at best it will be a nasty hack to get this S/W running on the Mac.

Performance issue with "Measure"

I'm encountering a performance issue in my application. Essentially I click a button, and a list is populated with databound data (this is virtualized because of the large amount of data), and then click another button which will add a row to an associated list view. I'm being vague because I think it's just necessary to illustrate how little is actually going on in the UI.
Here's what I know:
I don't see the issue on my my beefy dev computer running Win 7 Pro, nor on XP SP3 machines with decent specs. I only see it on a certain brand of laptops (Lenovo ThinkPads) running Win 7 enterprise with 4 GB RAM and Core i5 CPU (much beefier than the XP desktop).
Because of the aforementioned findings, I'm not thinking this is an issue with code.
I profiled with Microsoft's PerfView tool and noticed what I would assume to be an incredibly large number of calls to UIElement.Measure (not ever invoked directly by our code), something I don't see when I profile on the other machines.
The laptop has a 1360x780 resolution, so I thought that perhaps the small resolution was causing the GPU to unnecessarily render the controls because of some data binding that I might be doing (which might explain the large number of calls to Measure()). I extended the laptop's display to my 24" monitor and didn't see any improvement.
Right now I'm assuming that the issue is with the GPU. I've updated the driver with no improvements.
Even though I don't think it's an issue with code, is there a WPF equivalent to "SuspendLayout()"
Is there a way to profile GPU performance to see if it is being hammered during certain processes
(far shot) Has anyone had similar performance issues that seem to be computer specific and suggestions on how to track them down?
Sorry if this is a vague question. I tried to make it comply with SO's usage reqs. Let me know if you want any more info.
Just as an addendum: The program is using WPF, C# 4.0, the issue seems to be around Telerik controls (though I don't think they're suspect since we use them elsewhere without issue).
Turns out it's caused by a known Microsoft issue. I’d try to explain, but I won’t. Mainly because I can’t.
Article talking about fix (see post by Viðar on 3 August 2010):
Microsoft Hotfix site: http://support.microsoft.com/kb/2484841/en-us
Fix: http://archive.msdn.microsoft.com/KB2484841/Release/ProjectReleases.aspx?ReleaseId=5583
1. Answer
To to prevent rampant MeasureOverride calls originating from the WPF ContextLayoutManager:
protected override void OnChildDesiredSizeChanged(UIElement el)
{
/* base.OnChildDesiredSizeChanged(el); */ // avoid rampant remeasuring
}
2. Relevant citation
UIElement.OnChildDesiredSizeChanged(UIElement) Method   ...
The OnChildDesiredSizeChanged(UIElement) method has the default implementation of calling InvalidateMeasure() on itself. A typical implementation would be: do whatever optimization your own element supports, and then typically call base OnChildDesiredSizeChanged(UIElement) from a̲t̲ l̲e̲a̲s̲t̲ o̲n̲e̲ of the code branches...
...the implication (and fact-of-the-matter) being that, for any single parent layout pass originated by any one of its children, the parent's MeasureOverride will be called additionally—and likely extraneously—once for each of its children whose size(s) have changed as well.
3. Discussion
In the case where multiple children change their sizes "at the same time", the parent will typically detect and account for the new overall layout amongst all of its children entirely during just the first of these calls. This is standard practice in WPF, and is encouraged by MeasureOverride(…) deliberately excluding any indication of some specific triggering child. Besides the fact that in the most common cases there is no such child (see above link for details), it makes code for attempting any sort of "partial layout" onerous. But mostly, why would any layout calculation ever want to proceed without first obtaining all the very latest available measurements anyway?
So we see that after a single MeasureOverride call, triggered by whichever child happened to be "first" (it shouldn't matter), the layout of the parent should actually be final regarding all of its latest child size information. But this doesn't mean that any queued OnChildDesiredSizeChanged notifications—for other children whose size(s) had also changed—have gone away. Those calls are still pending with the parent, and unless the virtual base call is explicitly abandoned (as shown in bullet #1), each will generate one additional, now-extraneous MeasureOverride call.
4. Caveat
The code shown here disables a̲l̲l̲ child-initiated measure invalidations, which is appropriate for cases where the parent either willfully forbids such changes, or is inherently already aware of them. This is not uncommon; for example, it includes any parent that always fully determines and enforces the size of its children, or more generally, any parent that only adopts DesiredSize values from its children during its own measure pass. What's important is that the measuring of the parent be sufficiently guaranteed by its own parent only.
The situation where a parent might wish to cancel some of the child-initiated measure notifications while preserving/allowing others will naturally depend on additional particular circumstances. It seems more obscure, so it is not addressed here.

Update loop in windows forms?

I've been working with some game engines lately. They all have an Update() function that gets called every frame (not a loop in the strict sense of the word, but you get the idea). Any code you want to execute needs to be placed in here.
This made me wonder, how does this work in windows forms, as the only thing I use there is events?
(If the title doesn't explain it good enough, feel free to change it)
It basically works the same, it is only called the message loop, event loop or message pump
http://msdn.microsoft.com/en-us/library/aa383738.aspx

GLUT doesn't detect properly more then 2 keys pressed?

I'm trying to make a small game using (free)GLUT. I know that it's old and there are better alternatives, but currently I prefer to stick with it and use it as much as possible. I program with C.
I'm currently trying to make GLUT detect properly all the keys I press.
I use glutKeyboardFunc, glutKeyboardUpFunc, glutSpecialFunc and glutSpecialUpFunc to detect pressed keys and I store their state in a short array I created (I currently have only 5 usable keys, so I just created a specific array for them).
However, while everything works fine for 2 keys or less, the game doesn't detect properly 3 keys or more. While for some keys it detect the combination properly (that actually happens for only 1 specific combination), for others the functions simply don't detect the third key that I press.
I checked my code a few times, and there is nothing special about the combination that does work.
I also made glutKeyboardFunc and glutSpecialFunc directly print every key-press that they receive, and it seems they simply stop working after I press more then 2 keys.
Is it a known issue with GLUT or something? I googled a lot and didn't find anyone with a similar issue.
I am not very into GLUT but as I know, but you should make sure, that your keyboard supports more than 2 input keys at once. This feature is called n-key rollover. This page says, that 2-key rollover may be a common value for some keyboards, but you dont need to trust this source.
I'll clarify a point: The glutKeyBoardFunc is a callback i.e., it is invoked for every key pressed and re-executed over and over again and all the if-else (or switch-case) statements for various key combinations are executed. What it means is this - if you were to press 'A', '->' (right arrow) and 'D' all at once, depending on which key-press event was received first the callback will be executed accordingly. Sometimes with a delay and sometimes the on screen animation may stop momentarily.
GLUT is purely for educational/learning purposes but not good for full blown applications since that's not what it was designed for. You land up using OS specific libs or other languages (e.g., Qt) to embed OpenGL "window" within them and execute the keyboard events etc., The event handling in those (and/or OS specific frameworks) is radically different (and better) than GLUT.
You may want to keep your simultaneous key presses to a minimum. You may augment it with the mouse to get rid of the jerky response/processing...

Intercept WM_DELETE_WINDOW on X11?

I'd like to intercept the WM_DELETE_WINDOW message that is posted to a certain selection of windows that an application I'm writing (AllTray), so that I can act on it instead of the application receiving it. I'm currently looking at trying this at the GDK level via gdk_display_add_client_message_filter if possible, but I'd be happy with an Xlib solution if there is one as well; it seems to be possible, but I just don't seem to be understanding how I am to do it successfully.
Currently, I have two programs (written in C) that I am trying to use to get this figured out, the first one does nothing but create a window and register that it knows about WM_DELETE_WINDOW, and the second one attempts to catch that message, but seems to fail in doing so; it appears to do precisely nothing. Am I understanding the documentation wrong on this, or is there something additional that I need to be doing (or do I need to avoid using GDK entirely for this)?
The background is this: Prior to my re-write of AllTray, the way it would do things appears to be to try to intercept a mouse-click on the X button itself. For some window managers, this worked properly, for others it didn't work at all, and for others, the user had to configure it manually and instruct AllTray where the button for closing the window was. What I am looking for is a solution that doesn't involve a LD_LIBRARY_PRELOAD and will work for any window manager/application combination that conforms to the current standards and sends a WM_DELETE_WINDOW ClientMessage when the window is closed.
UPDATE: I'm still looking for an answer. The route that I am taking at the moment is to try to reparent the window and manage it myself, but I just cannot make it work. Upon reparenting, I don't seem to be able to get it back in any way. I may be missing something very fundamental, but I can't figure out how to actually make it appear it my own window again, to bring it back on the screen.
UPDATE 2: Alright, so I've hit another brick wall. The X server documentation says to set the StructureNotifyMask on the window's event mask to receive both MapNotify and ReparentNotify events. I'd be interested in receiving either. My current thinking was to create a window that served just as an event receiver, and then when I get events for interesting things, act on them by creating and reparenting. However, this simply doesn't seem to be working. The only events I actually receive are PropertyNotify events. So, this route doesn't seem to be doing very much good, either.
I don't know X11, but I googled using "Intercept WM_DELETE_WINDOW X11" as keywords. Found 17k - MarkMail and Mplayer-commits r154 - trunk/libvo. In both cases they are doing the same thing.
/* This is used to intercept window closing requests. */
static Atom wm_delete_window;
within static void x11_init(),
XMapWindow(display, win);
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, win, &wm_delete_window, 1);
then, within static int x11_check_events(),
XEvent Event;
while (XPending(display)) {
XNextEvent(display, &Event);
if (Event.type == ClientMessage) {
if ((Atom)Event.xclient.data.l[0] == wm_delete_window) {
/* your code here */
}
}
}
See XInternAtom, XSetWMProtocols and XNextEvent.
After I wrote the above, I found Handling window close in an X11 app:
When a user clicks the close button
[x] on our X11 application we want it
to pop a a dialog asking “do you
really want to quit?”. This is a plain
X app. No fancy GTK or QT widgets
here. So how to catch the “window is
being closed” message?
The answer is to tell the Window
Manager we are interested in these
event by calling XSetWMProtocols and
registering a WM_DELETE_WINDOW message
with it. Then we’ll get a client
message from the Window Manager if
someone tries to close the window, and
it won’t close it, it’ll leave that us
up to us. Here’s an example….
// example.cpp
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>
int main()
{
Display* display = XOpenDisplay(NULL);
Window window = XCreateSimpleWindow(display,
DefaultRootWindow(display),
0, 0,
500, 400,
0,
0, 0);
// register interest in the delete window message
Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wmDeleteMessage, 1);
std::cout << "Starting up..." << std::endl;
XMapWindow(display, window);
while (true) {
XEvent event;
XNextEvent(display, &event);
if (event.type == ClientMessage &&
event.xclient.data.l[0] == wmDeleteMessage) {
std::cout << "Shutting down now!!!" << std::endl;
break;
}
}
XCloseDisplay(display);
return 0;
}
Unfortunately, the best answer to this question is a series of non-answers; there are technically ways to accomplish it, but they all have downfalls that make them extremely impractical:
Create an X11 proxy for an application, passing all X11 protocol messages back and forth between the application and the X server. The proxy would then filter out any interesting messages. The downside to this is that this is an awful lot of overhead for a single little tiny feature, and the X11 protocol is complex. There could also be unintended consequences, which makes this an even more unattractive option.
Launch as a standard application that acts as an intermediary between the window manager and “interesting” client applications. This breaks some things, such as XDnD. In effect, it is not unlike the first option, except that the proxy is at the Window level as opposed to the X11 protocol level.
Use the non-portable LD_PRELOAD library trick. This has several downsides:
It is non-portable across dynamic linkers: not all dynamic linkers support LD_PRELOAD, even among UNIX-like systems.
It is non-portable across operating systems: not all operating systems support featureful dynamic linkers.
It breaks network-transparency: the shared object/dynamic link library must reside on the host as the child process that is being executed.
Not all X11 applications use Xlib; it would be necessary to write one LD_PRELOAD module for each of the libraries that an application might use to talk with X11.
In addition to the last point, not all applications would be susceptible to LD_PRELOAD even if they ran under a linker that supported it, because they may not use a shared object or DLL in order to communicate with X; consider, for example, a Java application which uses an X11 protocol library written in Java itself.
On some UNIX-like operating systems, LD_PRELOAD libraries must be setuid/setgid if they are to be used with setuid/setgid programs. This is, of course, a potential security vulnerability.
I am quite sure that are more downsides that I cannot think of.
Implement an extension to the X Window system. Non-portable among X11 implementations, complex and convoluted as all get out, and absolutely out of the question.
Implement extensions or plug-ins to window managers. There are as many window managers as there are opinions on window managers, and therefore this is utterly infeasible.
Ultimately, I was able to finally accomplish my goal by using a completely separate mechanism; anyone who is interested, please see the Close-to-Tray support in AllTray 0.7.5.1dev and later, including the git master branch available on github.
Ok, to elaborate on my earlier suggestion, you might want to investigate XEmbed. At the least, that might give you some ideas to try.
Failing that, I'd have a look at how other similar software might be working (e.g. wmdock, or how GtkPlug/GtkSocket is implemented), though I believe in both those cases explicit support is required in the applications.
Hope that is more helpful.
You should read ICCCM that tells you how window manager communicates with client. Most of WM will create a frame window to contain your top-level window via reparenting. Thus, if your reparent may break the relationship known by WM and your client window.

Resources