Microsoft Web Browser ActiveX control - printing to a specified (non default) printer - windows

I'm using the MS Web Browser ActiveX control in a native C++/Win32/MFC dialog application to render some information via HTML.
I'd like to print the contents without any user interaction to the specified printer (which is not the default printer). The printer I'd like to use is a PDF printer.
I'm using a nice wrapper class from Code Project which makes the using the Web Browser control a little easier (http://www.codeproject.com/Articles/3919/Using-the-WebBrowser-control-simplified) and one of the things that wrapper provides is printing. It provides a print method which uses ExecWB(OLECMDID_PRINT,OLECMDEXECOPT_DONTPROMPTUSER,...) to initiate printing of the contents.
This works great and results in the contents of the control being printed to the default printer without any user interaction.
The challenge, then is to have it use a different printer than the default. My initial attempt was to call ::SetDefaultPrinter (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162971(v=vs.85).aspx). This doesn't seem to work. It seems that, despite calling ::SetDefaultPrinter, the web browser ActiveX control still prints to the system default printer. Its as though it ignores whatever this call does.
I tried broadcasting the system settings change message as suggested in the MSDN link as well as directly sending it to the browser window without any luck.
Any ideas how I can get the web browser activex control to print the printer I specify instead of using the default printer?

What I do in addition to all your steps is set the printer in the IE registry, here:
HKCU\Software\Microsoft\Internet Explorer\PageSetup\printer="the required printer name"
And restore everything back after the printing

I got it working. The reason for the problem was NOT that the browser control was printing to the wrong printer, it was that the printing operation (via ExecWB) is performed asynchronously. So, I was setting the default printer to the PDF printer, then initiating the print, then restoring the original default printer. This happened quickly enough that by the time the asynchronous print operation was ready the original default printer was set as the default again and so it went to that printer.
The solution was set the default printer to the PDF printer, initiate the print, then wait for the print completion callback. Once that callback is received, it then restores the original default printer.
If you're using Gary Wheeler's excellent web browser control on Code Project (see here), its very easy to get the print completed callback, you just override the virtual OnPrintTemplateTeardown() method.

Related

Preview handler dll permissions issue

I'm creating a preview handler dll for a custom graphics file type associated with an application I've developed. For various reasons the preview handler dll is not able to render the graphic for the preview itself. Instead I'm attempting to do it in the following way.
My graphics application associated with the file has been modified to accept specific command line parameters (file path, width, height). With these parameters the application loads the file, renders an image and saves it as a .png file in the user's AppData/Roaming folder and then terminates. This works fine if I call the application from the command line with valid parameters. The .png is created as expected.
When the preview handler is run it calls the application with command line parameters for the file being previewed and dimensions of the preview pane. It does this using the windows function CreateProcess and waits for the application to terminate before continuing.
The preview handler then loads the .png file and draws it to the preview pane.
The problem I'm experiencing is in the second step. The preview handler calls the application but the application gives an error that it is unable to save the .png file ("Cannot create file. Access is denied"). It seems that the application is being run with less permissions when executed by the preview handler than when I run it myself from the command line.
I have tried changing the save location of the file such as user's AppData/Local the shared ProgramData folder and the application's location, but all give the same result. I've also tried setting various CreationFlags in the call to CreateProcess, but none of them help.
Does anyone know why the application doesn't have permissions to save a file when called from a preview handler and is there anything I can do to get it to work? I realise that this is an unusual way of implementing a preview handler, but it's the easiest way without porting a lot of code. Another advantage is that I'm not replicating the rendering code in the main application and the preview handler, which means that the preview handler can be much smaller.
Note that I'm running on Windows 10.
Does anyone know why the application doesn't have permissions to save a file when called from a preview handler and is there anything I can do to get it to work?
Per the documentation:
Preview Handlers and Shell Preview Host
Preview handlers are called when an item is selected to show a lightweight, rich, read-only preview of the file's contents in the view's reading pane. This is done without launching the file's associated application.
...
By default, preview handlers run in a low integrity level (IL) process for security reasons. You can optionally disable running as a low IL process by setting the following value in the registry. However, it is not recommended to do so. Systems could eventually be configured to reject any process that is not low IL.
HKEY_CLASSES_ROOT
   CLSID
      {YOUR HANDLER'S CLSID}
         DisableLowILProcessIsolation
Another advantage is that I'm not replicating the rendering code in the main application and the preview handler, which means that the preview handler can be much smaller.
I would suggest moving the rendering code into a DLL. Export a function that takes a file name/pidl/stream and a target HDC as parameters. The function can read from the file and draw to the HDC as needed. The main app and the preview handler can then share the DLL, calling the function when needed to render the file directly to their respective UIs. You won't need to create a temp .PNG file at all.

Determining if currently renaming a file in Windows Explorer

I am trying to check a Windows Explorer view to see if a file name is currently being renamed / edited when typing.
I have a system hook installed that monitors the keyboard for specific keystrokes and fires certain events. This is done in this manner:
If the keyboard hook sees the key pressed it fires a message to another thread and continue processing other system hooks.
Other thread receives the message and checks to see if an Explorer window is active and gets the interface to the IFolderView2.
Call IFolderView2::GetFocusedItem() to get the focused item in the folder view.
Check if the focused item is being renamed / is in edit mode (SVSI_EDIT) using IFolderView2:: GetSelectionState() - this is the part that fails
If not in rename mode perform an action on that file.
I've tried everything on Windows 7 but the SVSI_EDIT flag (0x00000002 specifically) is never returned. It's always (SVSI_FOCUSED | SVSI_SELECT) regardless of if the file is being renamed. Setting the SVSI_EDIT flag with works with IFolderView::SelectItem with the flag puts it into rename mode but I want to determine if it's in this mode already.
This has only been tested on Windows 7 x64 so far.
Does anyone know a way to determine if Explorer / the IFolderView etc. is currently in the rename file state? Any sneaky method will do if it's not possible through these interfaces.
If one file in in renaming mode, Windows will create a EDIT control at the position of the item. So things got straight:
Find the currently-focused control.
Get the CLASS of the control.
Check whether it's CLASS is an EDIT.
On CodeProject there is a great example about how to find the focused control. To get the CLASS name of that control, use GetClassName API.

Open TFS Work Item Attachment in Image Viewer not Web Browser

Is there a way to open an attachment for a TFS work item by double clicking on it (or rather just opening it from the IDE) in your computer's default image viewer, rather than opening it in a web browser? I'd love to be able to change this setting (if it is a setting).
Edit: after reviewing Kate Gregory's response, I looked into this option and realized that the trouble is that VS is launching a url (a handler file to respond with the attachment), which results in the default web browser being launched. A potential work around i'm considering is writing a custom mapper for all web based calls (as in, when going to start->run and enter a URL) that the mapper would determine what kind of call it is (TFS, etc) and use an appropriate program, based on the MIME type responded with, with a second phase to be incorporate this as a VS add-in.
I'm reasonably sure VS just uses your default program. Word for .doc files, IE for .htm files, and (in your case I bet) IE for .jpg files. Try changing the default program you're using in Windows and see what happens.
All files saved in TFS are saved in a path that starts with the following address:
http ://{YourServerName}TFS01:8080/tfs/.../.../...&FileName={YourFileName}.{YourExt}
This means that all files are opened using the default program defined for HTTP protocol, regardless of the extension for your file.
You can probably change the default program for your HTTP protocol (if you have permissions, and usually you wouldn't) but this would also affect opening any regular web page or URL, which is probably not recommended.
I still haven't found a workaround this issue too.
Some kind of preview function in VST/Team Explorer would be nice. Then, only a minor of attachments must be opened in the browser.
http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6224713-preview-attachments-in-team-explorer

Windows: Language Bar will not show input method options for some of my windows

I am trying to make our application properly handle international input. Since we handle text input and font rendering ourselves, I wrote custom code to handle the respective WM_IME_* messages.
Now, this all works fine, with one exception: When our applications main window is open, the Language Bar will not let me pick any options. I can set the input language to Japanese or Korean, but the menus for choosing the input methods (like Hangul or Hiragana) are not shown. Then, when I open another window (any other window, be it one of our application windows, or a standard "save file" dialog), the options appear. Once there, they will stay, even if I close the other window. IME input will then work as expected in the main window. But, as explained, only if I open another window first.
Now, how does windows decide whether it should display the input method options or not? It appears that windows does not recognize our main window as Unicode capable for some reason. How can I fix that?
Thanks in advance for any suggestions,
jonas
Edit: One more strange thing i noticed is that for my main window (which will not let me change input methods), I will get a WM_INPUTLANGUAGECHANGEREQUEST message when i change the input language - which I pass on to DefaultWindowProcW. For the windows which let me change the input method, i don't get the request, i just get a WM_INPUTLANGUAGECHANGE message (which I don't get for the other window).
Ok, after a long search I've been able to find out what is breaking this. We are calling SetFocus on a child window in response to WM_FOCUS messages, so that a specific child window always gets focused when a window is brought to the front. Apparently, this confuses window's IME code, and makes it unaware that the window can handle IME input.
Some notes
Text Service is works per window, not system wide, so even its turn on in one window, another window will still need to turn it on, (unless user set it as default)
And Text Service is not working in any windows, to enable that, target computer need to enable following setting on

How do I send control characters to a Windows printer in Crystal Reports?

We are trying to build a Crystal Report that sends control characters directly to the printer, without going through the (buggy) Windows driver for that printer. Does anyone know a way to do this from within a Crystal Report?
The specific control character we are trying to send is CHR(2). However when we put that in a Crystal Report, and print to a Generic Text Only printer, it is converting the character to a period on output. The character appears as a box in Crystal's preview, so I suspect it is the Windows driver, rather than Crystal, that is the problem.
The device is a Datamax printer. We do have drivers for it, but are encountering various problems - the infrastructure group knows more about the problems than I do, I don't feel I have enough information to try and ask about the specific problem. It is some combination of the interplay of Crystal Reports, Citrix, our market-specific ERP package, and automatically selecting label printers for the appropriate label size based on user at the time the report is run.
Short answer is you can't. In the end it's a due to the fact that apps like Crystal only speak at the GDI level and hand this data to the printer driver to be converted to PCL/PS etc. and passed onto the printer.
What type of device is this? What are you trying to accomplish?
If there is a driver that works but isn't the specific one for the device you can use that. Another option, which is a little 'hacky', is to use the Mini Driver Development kit and build your own. We've done this for customers where we insert our own codes for things like a custom size of paper in where letter size is specified to work around apps that don't support a custom size of paper or have some special font we need to access. Also, there are some printers that allow you to change the escape character to something else, depending on your device that might work OR build a post process whereby you print to file, the file is picked up, you modify the print file by looking for some special syntax you entered and pass the file on...painful, but could do the trick.
Generally you cannot send escape characters directly to printer from Crystal Reports.
If you only need special character at the start or end of report (like paper cut or drawer open for POS printers), then you may use Generic Printer driver device options and describe Start or End Job sequence.
I personally have always found some working (or compatible) driver for any printer (what is your printer model, BTW?). For POS printers drivers often include specific "font", allowing send escape sequencies directly.

Resources