Word 2007/2010: Accessing Microsoft.Office.Interop.Word.Document.SaveFormat property crashes Word - ms-word

We are trying to access the SaveFormat property of a Microsoft.Office.Interop.Word.Document instance (I guess it's technically a DocumentClass instance since Document is an interface). Upon attempting to read SaveFormat, Word crashes rather ungracefully. Wrapping the access in a try..catch block is no good, either; control is getting passed to another assembly which decides to terminate the app rather than throwing the exception for me to re-catch.
This occurs whether I'm simply reading the property in code, like this:
WdSaveFormat saveFormat = this.document.SaveFormat; // document is a Microsoft.Office.Interop.Word.Document
Or when I access the property in a Watch using the debugger.
I suspect the document instance itself is fine; its other properties (e.g., Path) can be reflected on. Running a quickwatch on the document object yields legitimate-looking values rather than a bunch of red-flag-raising "could not evaluate", "null", etc. values. I can scroll down line-by-line in the Quickwatch window and once it gets to SaveFormat it blows up.
The crash occurs in Word 2007 as well as Word 2010.
I've tried both embedding the PIA types and not embedding them ("Embed Interop Types" flag in reference properties)
I've tried referencing the Word 2007 PIAs instead of the 2010 versions. Same behavior.
We're targeting .NET 4.0 in our projects, but I've also tried targeting 3.5. No change.
Any ideas? About to defenestrate my comp :)

It turns out the document was a zero-byte file. Our bad, but it would have been nice had Word thrown a helpful exception (similar to what happens when you try accessing Application.ActiveDocument with no document open) rather than just blow up. Oh well, grand mystery solved. :) Thanks 0xA3 for suggestion that maybe the document itself was the issue. Ever get on one track of thinking and forget to look at the obvious?

Related

Text from UIAutomation property value truncated to 4k

I'm using UIAutomation from a 32-bit C++ application on Windows 7 to get the text content of windows of other processes. I noticed that the API always returns strings truncated to exactly 4096 characters if the text in the windows is longer than that. This happens both with the GetCachedPropertyValue() and the GetCurrentPropertyValue() calls, for both the UIA_ValueValuePropertyId and UIA_LegacyIAccessibleValuePropertyId property Ids.
Tested, among others, against 32- and 64-bit Notepad.
When I retrieve the text using SendMessage and the WM_GETTEXTLENGTH and WM_GETTEXT messages, the complete, untruncated text is returned. (This I currently use as a workaround.)
Looking through the documentation, I can nowhere find any mention of this limitation or how to get around it, which I would expect if truncation was by design.
I found a similar question on stackoverflow but there truncation was apparently due to the Visual Studio debugger, not to the UIAutomation API. However, this question makes it clear that UIAutomation should be able to return very long texts.
Googling the issue leads to another question on stackoverflow that also mentions the 4096 character limit, but unfortunately that question and any possible answer is deleted.
Perhaps the properties UIA_ValueValuePropertyId or UIA_LegacyIAccessibleValuePropertyId are not the correct one to use, but I failed to identify a better one.
Can anyone point me out what I'm doing wrong, or have suggestions for what I could try? Pointers to pieces of documentation that I obviously missed are welcome, too.
TIA
The exposition of the value is here for convenience but has limited capabilities. Instead, you must use TextPattern and it's DocumentRange property. This is explicitly specified here.
From it you can use the GetText(-1) method to retrieve your data.
You can code it like that :
string GetText(AutomationElement ae)
{
return (ae.GetCurrentPattern(TextPattern.Pattern) as TextPattern)?.DocumentRange.GetText(-1);
}

Borland C++ TComboBox

if have a problem with my Borland C++ 6 and a form.
In my project I have a list of members of a group that are inserted into a TComboBox. So far so good. Now I want to access the objects inside when I change the entry in this TComboBox. Now here's the problem:
Box1->Items->Strings[Box1->ItemIndex] returns the string of the person I chose. But when I want to access the Objects inside Box1 with
Box1->Items->Objects[Box1->ItemIndex] this will always return NULL...
In the last versions of the project it worked well. I tripple checked every object, every SQL everything I could think of. But nothing changed in context to the TComboBox so that this will return nothing anymore like it did before...
Do you guys have an idea what could possibly go wrong here?...

How do I Call SMSFormatMessageCtl.FormatModuleMessage?

I'm attempting to query the server for particular status messages and build the string format of them. The status message data doesn't contain the translated strings. They appear to be stored in srvmsgs.dll in the install directory for the console.
I see some "documentation" (proof that it exists, not help for using it) about the FormatModuleMessage method of SMSFormatMessageCtl. Sadly, there are no examples that I can find. This guy mentions that he has gotten it to work, but he doesn't provide details. In fact, I cannot even find the DLL referenced (FormatMessageCtl.dll) on my computer. StatView.EXE (the status message viewer app that comes with the client) exists, but running the dependency walker on it doesn't reveal any overt reference the desired .DLL.
Can this be done in VBScript or, preferably, PowerShell? I'm actually using Perl, but this is probably less common and nearly impossible to find meaningful code examples for. A working VBScript or PowerShell example would be a good place to start.
“About Configuration Manager Component Status Messages” has an example, but I think it’s in C# or C++.
Any suggestions on how to accomplish this?
I'm that guy. It's been 2 years, but I think the way I did it was that first I did a regsvr32.exe for the dll to register it, and then I just created an SMSFormatMessageCtl object through COM
For PowerShell that would be
New-Object -COMObject SMSFormatMessageCTL
For Perl, it's been even longer, but if I recall correctly, that would be
Win32::OLE->DispatchEx('SMSFormatMessageCtl');
Once you have the object you can call the FormatModuleMessage method, and don't forget the part about doing a bitwise OR of the Severity and MessageID from the WMI objects.

Why does the Function Module name of a Smartform change (sometimes)?

Not really critical question, but i'm curious
I am working on a form and sometimes the generated function name is /1BCDWB/SF00000473, and sometimes /1BCDWB/SF00000472. This goes back and forth.
Does anyone know what's the idea behind this? Cuz i'm quite sure it's not a bug (or i might be wrong on that).
It is not a bug. You always have to use SSF_FUNCTION_MODULE_NAME to determine the actual function module name and call it dynamically using CALL FUNCTION l_function_module.
Smartform FMs are tracked by internal numbering and thats saved in the table STXFADMI. You would always notice the different number in Development System if you have deleted any existing Form. Similarly, you would also notice the different number in your Quality system based on the sequence the forms are imported in QAS and the forms as well (as test forms are not migrated to QAS.
Similar behavior is also true for Adobe Form generated FMs.
You need to understand that every smartform has a different interface and hence the automatically generated function module needs to have different import parameters.
Due to this reason the 'SSF*' FMs generate a FM specific for your smartform. The name of the 'generated' FM changes when you migrate from one system to another. And that's the reason why you should use a variable while calling the 'generated' fm and not hardcode it.
The same goes with Adobe form as someone has rightly said in this thread.

Clang static analyzer on iPhone app showing errors with latest version

When I run my code through the version 252 checker binary, there are no analysis errors. However, when I change to use the latest 253 checker, it returns a slew of errors, all of which do not make any sense. For example, here is an image of an error that it shows in my Safari browser after the scan-build script is complete:
This is a pretty common error that shows up in the error listing. As you can see, the method name has Copy at the end of it, but it is still reporting as incorrectly named.
Here is the breakdown of errors that I am now getting with checker version 253:
Bug Summary
Results in this analysis run are based on analyzer build checker-253.
Bug Type Quantity
All Bugs 83
Dead code
Unreachable code 17
Memory (Core Foundation/Objective-C)
Bad release 19
Leak of returned object 23
Object sent -autorelease too many times 24
The autorelease errors seem to be related to the fact that the analyzer is unable to see that the Copy methods are actually correctly named, and I tried to look for an example of unreachable code, but I could not really find any patterns or explanations of those errors, as the errors were all lines of code inside simple if statements. Here is one for example:
I suppose that this could be some bugs that were introduced in the latest version of checker that is causing these to show up as errors. Is there something else (some kind of build setting or issue with the scan-build script) that I could be missing here?
First, method names should start with lower case letters, not uppercase (save for abbreviations like URL). It may be that the static analyzer is tripping over the uppercase "Get".
Next, even with a lowercase "get", the method does not follow convention.
To quote the documentation:
Use “get” only for methods that return
objects and values indirectly. You
should use this form for methods only
when multiple items need to be
returned.
Thus, the analyzer is correctly identifying an issue.
I would suggest following the guidelines and using something like:
+ (NSArray *) modifiedOrNewPeople: (FMDatabase *) aDatabase;
Which would release an autoreleased array. If there is some reason you can't return an autoreleased object, please comment.