VB6 calls to ActiveX component with string parameters yield weird results - string

I'm currently finishing a piece of software a now gone co-worker started.
The app is coded in VB6 and uses a 3rd party ActiveX component to act upon a 3rd party system. Our solution is basically an integration between their company's software and ours.
The issue I'm having is that there's a method call that fails consistently, even though it's passed perfectly valid parameters on our side (it's a login method). However, when I look at the trace their application offers, I see that instead of the username I specify, it tells me (roughly) "User '⚠⚠⚠' can't login".
I figured it was likely to be an encoding issue as the ⚠ character replacing the characters I give it to log on seem to be there because the characters are unknown, but nothing I did could fix it.
Anyone know of an issue with VB6 communicating with ActiveX components like this? Or anyone have an idea what I could try? I'm at a loss here and if the issue is on their side, it'll be a pain to get it fixed as we don't have their source code.
Thanks in advance.

There are a couple of ways of passing strings. Aside from the obvious one of passing a string as in
DIM u As String
DIM p As String
u = "Username"
p = "Password"
Set objIRC = objRCL.Login(u, p)
there's also the possibility that .Login is expecting pointers to String, in which case code
Set objIRC = objRCL.Login(StrPtr(u), StrPtr(p))

Related

String.Contains doesn't work on web exception because it has a small dots between the words

I am checking if a web exception message contains a string I have.
My string is: "The remote name could not be resolved"
The web exception message is:"The remote name could not be resolved:"
You would expect it to work, but if you copy-paste and enlarge the web exception here you will notice tiny dots between every word.
Those dots apparently ruins the contains function I use.
If exWeb.Message.Contains("The remote name could not be resolved") Then
'Do something...
End If
How can I compare those strings without the dots or ignore the dots or any other solution?
Relying on the message string isn't very future proof, as the framework developers may decide to change the message in the future for various reasons (to make it more explanatory, change grammar .etc.) or your code could be running in a different locale with a different language causing the error message to be different.
I suggest you check the Status property instead.
See the documentation of the Enum. I think you're looking for a WebException with a Status of NameResolutionFailure
https://msdn.microsoft.com/en-us/library/system.net.webexceptionstatus(v=vs.110).aspx

VBA Excel - Macscript causing problems on windows when using IIF

I'm creating a macro that opens a file that everyone has on their computer and in order to do so must know the person's username / work ID.
To get the person's work ID I've tried using the following:
sso = IIf(InStr(Application.OperatingSystem, "Windows") = 1, Environ("UserName"), _
'MacScript("(user name as string)"))
Running this on windows returns an error because of the Macscript (I think) and I'd assume the same would happen vice versa, even though the error part of the IIF is never actually accessed I'm guessing seeing as the whole line is executed this is why there is a problem, thus On Error Resume Next would not really help here.
I know this can be easily overcome by just using an if and else statement but I just want to know if I'm right / why this problem occurs and if there are any other more sophisticated ways of achieving what I want.
Thanks
The IIF function evaluates both the true and false parts, or rather it attempts to do so. There is no short-circuit. Your assumption about why it's failing (and also that you can't use an OERN) is correct. You may take a look at conditional compilation logic, if certain parts of your code will not compile on Windows (or Mac, respectively).
http://msdn.microsoft.com/en-us/library/aa240847(v=vs.60).aspx

String to XNamespace Implicit Conversion inside a BizTalk Orchestration

I am a bit confused by what I see and hence headed over to SO.
I am developing a BizTalk (2010) Orchestration and I am wanting to parse an incoming XML message. I just need to retrieve then number of times a particular node is repeating. I could have used XPath. But, I chose to use LinqToXml.
I have created a variable of type System.Xml.Linq.XNamespace and inside an expression shape, I am assignning it a string value.. say http://mycompany/v1.0. This is a perfectly valid C# statment, as there is an implicit conversion from String to XNamespace (MSDN link).
But the Orchestration will not compile at all. I get this error cannot implicitly convert type System.String to System.Xml.Linq.XNamespace.
And if I dont use the XNamespace variable and directly run LinqToXml on the incoming message like this
MessageCount = MyXElement.Elements("{http://mycompany/v1.0}ListOfNotifications").Elements("{http://mycompany/v1.0}Notification").Count();
I get a cannot convert from String to XName error. Even this is confusing.
I am using BizTalk 2010 and C# 4.0. Can someone explain if I am missing something? I have tried all these code snippets using LinqPad and I get the expected response. So, there are no typos or missing references.
I opted to use the XPath option to retrieve the values that I needed, instead of using LinqToXml. The code that I ended up writing looks like below:
xpath(myOrchVariable, "string(/*[local-name()='InputRootNode' and namespace-uri()='http://my/name/space'])")

Input string was not in a correct format when parse in multithreading

Does Anybody can explain this:
How does it possible to throw exception when parsing "55.01"? I use multithreading.
--edit--
but... sometimes it works
This realy make me sad ;(
i use .NET 4.0 and VS2010.
--edit 2---
Ok, I made a little progress. When I do not use multithreading everything works perfect. But when I use multithreading (probably)one of a thread throw FormatException in place which is shown in the picture.
It's possible the system is set for some culture that expects a comma as the decimal point.
From http://msdn.microsoft.com/en-us/library/fd84bdyt.aspx:
The s parameter is interpreted using the formatting information in a NumberFormatInfo object that is initialized for the current thread culture. For more information, see CurrentInfo. To parse a string using the formatting information of some other culture, call the Double.Parse(String, IFormatProvider) or Double.Parse(String, NumberStyles, IFormatProvider) method.

Delphi Translating Strings

I'm using Delphi 2007 and I wonder how the following problem can be solved:
I have to translate AComp.Caption for example, but the string that I want to assign to the caption, often depends on some data (for example a date or a number, that gets Formatted). Therefore I have to save the data and the string in a new variable for every translation, which is really annoying.
What I want to do is something like that:
// will add the string and data to an internal list of Translator
// and will then return a DynamicString, which represents the translated value
AComp.Caption := T.NewTranslatedString("Hello %s, do you like cheese?", User)
(Note that AComp.Caption ("Hello %s..") can be changed in different methods)
When switching to another language, you would call T.TranslateAgain() and the value of all strings will be translated and, if data given, formatted again.
Is this possible or do you know another way for solving the given problem?
Thanks in advance
Additional question:
Are strings normal objects, that I can subclass and add dynamic behaviour that changes the string itself in special cases?
Delphi strings are not objects, you can't add behaviours to them. You would need to develop your own class.
The Windows way to localize applications is to get advantage of resources, that can be changed (and loading redirected) without changes to the code (no need to call special functions or add new components), and without run-time calls but to load the resource. The only disadvantage of resources is they cannot be changed easily by the end user. The Delphi 2007 standard localization tools use this approach.
Anyway there are some libraries like dxGetText (which is a port of the GNU gettext library) or TsiLang, for example that use a more "intrusive" approach, requiring changes to your code or adding components. In exchange they can simplify end-user localization.
Before developing your own localization library, I would check if one of the existing ones fits youe needs.
Note: Be aware that Delphi localization tool has significant issues that weren't fixed until XE (which I didn't test yet). See for example QC #79449. Unluckily the fix was never backported to earlier releases.
You can use Delphi's own translator tool. It is able to extract strings and resourcestrings from your source code and form DFM files, and gives you a graphical user interface to translate them to any language. It then creates a resource DLL for each language. The DLL containing the translated strings and DFM data. You should deploy this translation DLL with your project to the destination machine.
In your case, your strings are divided into two groups; fixed strings which do not need any further processing, and parametrized strings which need some additional data to be formatted properly. For the fixed strings, you can just type in the translation into translator tool. For parametrized strings, save each one as a resourcestring and use the resourcestring for formatting them. For example:
resourcestring
strDoYouLikeCheese = 'Hello %s, do you like cheese?';
...
AComp.Caption := Format(strDoYouLikeCheese,[User]);
Now you can use the translator tool or any resource editor to translate the resourcestring into your desired language without the need for changing your source code or recompiling it.
What you want to do is to localize your application. Delphi has support for this, based around the resourcestring keyword. However, I've never done any localization myself so I recommend that you do some websearch for this topic or perhaps wait for the other experts here to supply more detailed help!
You could use a dictionary to keep track of the string mappings, something like this
TTranslator = class
private
FMappings : TDictionary <String, String>;
public
function Translate (const SrcStr : String) : String;
procedure SetMapping (const SrcStr, DestStr : String);
end;
function TTranslator.Translate (const SrcStr : String) : String;
begin
if not FMappings.TryGetValue (SrcStr, Result) then
Result := SrcStr;
end;
procedure TTranslator.SetMapping (const SrcStr, DestStr : String);
begin
FMappings.AddOrSetValue (SrcStr, DestStr);
end;
Translating would then be simply several calls to SetMappings. This gives you a lot of flexiblity. Anyway, you might consider using the built-in localization support or even third-party solutions.
EDIT: Just saw that you are using Delphi 2007, so you don't have TDictionary available. The idea should remain valid, just use any dictionary implementation or a list-based approach.
And to answer the other part of your question: no, strings are not normal object (actually they are not objects at all). They are special in various ways (memory management, copy-on-write behaviour) and it is not possible to subclass them. But that's not what you want anyway if I understood the question correctly.

Resources