How might one cope with the ambiguous value produced by GetDllDirectory? - winapi

GetDllDirectory produces an ambiguous value. When the string this call produces is empty, it means one of the following:
nobody has called SetDllDirectory
somebody passed NULL to SetDllDirectory
somebody passed an empty string to SetDllDirectory
The first two cases are equivalent for my purposes, but the third case is a problem. If I want to write save/restore code (call GetDllDirectory to save the "old" value, SetDllDirectory to set a "new" value temporarily, and later SetDllDirectory again to restore the "old" value), I run the risk of reversing some other programmer's intent.
If the other programmer intended for the current working directory to be in the DLL search order (in other words, one of the first two bullets is true), and I pass an empty string to SetDllDirectory, I will be taking the current working directory out of the DLL search order, reversing the other programmer's intent.
Can anyone suggest an approach to eliminate or work around this ambiguity?
P.S. I know having the current working directory in the DLL search order could be interpreted as a security hole. Nevertheless, it is the default behavior, and my code is not in a position to undo that; my code needs to be compatible with the expectations of all potential callers, many of which are large and old and beyond my control.

No fix for this. Between a rock and a hard place, you ought to assume that NULL was passed. There is already a way to enable safe searching with a registry setting.

Related

Using did as boolean flag name

I named one of my boolean parameters didInfoChange.
Many people on my team tell me to change it to isInfoChanged, which I don't agree. It maybe because my team members aren't native English speaker (neither am I), but I feel that ifInfoChanged is just isn't right.
didInfoChange -> Did information change? -> True/False
is pretty understand in my oppinion
isInfoChanged -> is info changed?
just does not sound right.
It's probably not a big deal to fight about this, but I did some search and people do not really use did for flag name. I'm ok with hasInfoChanged but has and did is basically the same thing.
I'm wondering why is did not ok?
There are two questions here:
1) Which is better, didInfoChange or isInfoChanged?
The English word "change" can be transitive or intransitive, but in this context it is clear that "the info is changed" and "the info did change" mean exactly the same thing. (There is a subtle difference in connotation, but it is of no importance here.) The two names have the same length. There seems to be no difference except style convention.
2) If your way is better than theirs, what should you do?
Consider the consequences of your actions.
If you have the power to persuade the rest of the team to use your variable name, at no cost, then do so. If doing so would cause stress (e.g. by commanding your subordinates to do something they consider a bad idea), then the improvement in style probably isn't the cost to the group dynamic.
If you cannot persuade them, but you can prolong the argument and prevent the team from doing constructive work, then... don't. Use their variable name.
If you cannot prolong the argument, but you can make yourself unpopular by being argumentative, then... don't. Use their variable name.
Beside is it is also sometimes admissible to use has in naming Boolean getter-methods, depending on which auxiliary verb would be used in spoken language; I never saw did as part of a Boolean identifier.
With hasInfoChanged you would keep the participle ending (e)d. Maybe that satisfies the rest of your team.
infoChanged could be mistaken for an EventHandler-Delegate.
Unfortunately I am not a native English speaker, either.
It depends on the context and what this field "really" expresses in semantics.
didInfoChange puts emphasis on the completed action (past-tense implied) by "did" + action-verb
isInfoChanged puts emphasis and indicates the current-state when asking now by is + state; where the past-tense is indicated by the passive "changed"
Note: Info is the vague part in the name. is is a common indicator for boolean fields or getters - indicating a question (same like has or can). did is rather rarely used because we usually ask for the current state at runtime using is. The completion or history can be expressed by other parts of the name, like specific action-verb in past-tense.
Other ways of recording/asking for change
What about asking more about the context of this change:
Who did change the information ? Like an audit field (changedBy) conveying also who did change something.
When was the information changed ? Like a audit date/time field (changedAt), not only telling that it was changed, but also when.
What information was changed ? Like capturing the change itself (lastChange) which could also be null if not changed at all.
In most ORM-frameworks which capture audit-information like this (when/who/what was changed) we can see fields like createdBy or createdAt for the initial user and timestamp when created, modifiedBy or modifiedAt for the user and timestamp that last updated or changed the object.
Sometimes also a version-indicator helps to keep track of the number of changes.
Keep it simple
One compromise could be inspired by KISS-principle:
Have a boolean field changed which could for enrichment-purpose also hold a timestamp along with a getter named isChanged to query the current state like asking a human question like:
is [this] changed ?
Note: [this] is implied when invoking the method on the object like this.isChanged().

Object name becoming lowercase

I have some code which has worked in multiple installations for about a year. Today im doing a small change to a control and then another control seems to have developed an issue. When at runtime im getting a 91 error object variable or with block variable not set.
I therefore looked at the problem line which is: -
If Screen.ActiveForm.name = "frmFoutmelding" Then Exit Sub
so I noticed the name was lowercase. if i delete .name and rehit the "dot" then it shows me i can use .Name but as soon as i move from this line it drops back to .name
I've checked for instances of name and it appears everywhere in the code in different modules but i cant find if i have accidentally defined this lowercase name anywhere?
Googling doesn't seem to show much but i feel Im googling the wrong terms
chaps - thanks for your suggestions - this was the first instance of the lowercase name and searching as Jim suggested didn't reveal anything I'm afraid. What I did discover was that this was suddenly being run before any forms had actually been displayed and so the count was 0. I therefore, did an on error to check the form count and exit the sub if it =0 then if not to carry on with the line I thought I was having issues with.
It's likely that you did create a new variable or property called (lower case) name, or that some included reference did the same. It's possible to use reserved words as variable names in some cases, but it requires taking specific steps.
I would first search your code for instances of name As to see if you created a variable (this assumes you use Option Explicit, which is a must IMO). Then search for Property*name with * as a wildcard.
If those fail you could try unchecking references or components to see if any of them define name. If none of that finds anything, please post back here.
Jim Mack covers a lot of the potential issues. I think another is if you typed a lower case '.name' in association with Activeform at some point earlier in the same code module - the VB6 IDE checks in the current module and uses that to define what case to use. Look further up the same code module (sub or function).
Ultimately, check what changes you made by comparing the old source to the new in a file comparison tool like windiff - you do have backups, right?

Hiding parameter prevents other parameters from refreshing

I have the first parameter (client drop down) that passes an ID to the second parameter to be used in the 3rd and 4th parameter. During testing all the parameters are set to visible to verify what's being passed. As soon as I hide that second parameter the rest don't refresh. Again, visible, correct info flowing through, hidden, DOA. I have this set up exactly like this on at least a dozen other reports with no issue. I'm not real sure where this going wrong since I can see the correct value being passed while visible?
I was able to duplicate your issue. While I can't find a reference to support my supposition, I believe that hidden parameters (even those with a default value) are not evaluated until rendering, which would explain this behavior. Data sets that drive parameter values are run prior to the report being rendered.
As you're talking about having trouble with dependencies between the parameter values, I assume you're using queries to drive your available values for parameters three and four. If this is the case, then simply embed the logic that relates the value(s) of parameter 1 to the value(s) of parameter 3 into the query that drives parameter 3's available values. By cutting out Parameter 2 and incorporating it into the query logic for parameter 3, you will work around this issue.
If you're having trouble accomplishing this, reply in a comment and I'll see if I can help. As it stands, I don't know enough about what you're trying to do to help any more.

Proper return value for TVN_KEYDOWN

I have very recently answered to the question about Creating TreeView with nodes and checkboxes.
While I was pondering how to properly process the case when treeview's node is checked when user pressing spacebar I ran into TVN_KEYDOWN notification.
My solution was tested in a dialog box and in a window procedure and both seem to work flawlessly.
Still, I have a dilemma of what should be my returned result. Here is the relevant excerpt from the documentation for TVN_KEYDOWN:
Return value
If the wVKey member of lParam is a character key code, the character
will be used as part of an incremental search. Return nonzero to
exclude the character from the incremental search, or zero to include
the character in the search. For all other keys, the return value is
ignored.
I have tried returning both results when testing if spacebar is pressed and haven't noticed any difference.
So I ask you the following questions:
Can someone explain me what is the incremental search ?
What is the difference when I include or exclude the tested character (spacebar) from incremental search ?
EDIT:
It seems that I have found an answer to first question. I have found an article on Wikipedia that explains what incremental search is.
It leaves only the second question to be answered.
END OF EDIT
Thank you.
Best regards.
It is most visible in a giant TreeView. The best example of one is the left panel in Regedit.exe. Expand HKCR and start typing to see the effect.
The implementation has changed across Windows versions, it used to be a lot less usable in XP. It is a UI blooper, there isn't any good way for the user to see that he mistyped a letter, to correct a typing mistake or to see that a search starts from scratch. Current versions of Windows use a timeout, automatically resetting the partially typed search phrase when you don't hit a key for a couple of seconds. Which is about as practical as it gets. It is certainly useful, just not very usable.
The only sane thing to do with TVN_KEYDOWN is nothing. Never add more ways to make it less predictable than it already is. Intentionally swallowing a keystroke of course makes it a lot less usable if it is a key the user really wanted to use. You certainly don't want to swallow a space, that's of course a valid character in tree node text. If the tree happens to not have any nodes with text that contains a space then you still don't want to swallow it, the control itself already does.
The notification would have been a lot more useful if it also passed the incremental search string that was collected or give a way to reset it. It just doesn't so that's water under the bridge. Consider handling it if you've created some kind of usability trap, very hard to come up with a practical example of one. You know it when you see it.
The only real use is to completely replace the search function. You'd then make your own rules and select a node yourself. And of course always return a non-zero value.
You want only answer to the second question, so this is:
If you exclude spacebar from incremental search, you dont find trewview item with spacebar.
Note: You must disable TVS_CHECKBOXES style, because treeview wndproc handle spacebar different with this style set.

Modifying parameters with code in Microsoft Reporting Services

I made a report with about 30 different rectangles and textboxes that have different visibility expressions depending on the parameters. (It's a student invoice and many different messages have to appear depending on the semester) When I made all the expressions I coded in the parameters in all upper case. Now I have a problem when users enter lowercase letters, the SQL all works fine since it is not case sensitive, but the different rectangles and textboxes don't show. Is there a way in the report code to first capitalize all the parameters before running the SQL? Or do I actually have to go back to every visibility expression and add separate iif's for upper and lower case? (That seems incredibly silly to have to do). I can't change my parameters to numbers because I have been given strict requirements for input. Thanks.
I do not know if this is the most elegant solution, but you could accomplish this by following this procedure for every parameter on the Report Parameters page:
1)Re-name the parameter, leaving its prompt as that of the old parameter.
2)Add a new parameter with the same name as the old parameter.
3)Mark this new parameter as Hidden.
4)Make sure that the new parameter's available values are marked as non-queried(available values will never be actually used.)
5)Mark the Default Values as Non-queried, using the following syntax:
=ucase(Parameters!OldParameterName.Value)
Can't you just UCASE the params (do it in the xml view, it will be quicker and you might even be able to do a regex find/replace)

Resources