Creating a UI to Print a Report in Access 2013 - c#

I have a carefully formatted report in Access 2013 and I'm trying to create a UI that will print this report upon a button click. I would be open to a C# WPF or Form app or perhaps an HTML page that could contain this button.
Does anyone know if this is possible and if so what the code would be?
My end goal is to have the user be able to print this report without having to access the database directly. I am open to other languages/platforms.

At the end of the day you still need Access installed, and at the end of the day you still have to launch Access, and at the end of the day you still 100% relying on Access.
Thus to print an Access report you still have to launch Access. It not at all clear why then you cannot built your required UI in Access since you still 100% relying on Access for this report.
You thus will have to automate Access and rely on Access. You can use any system or language that supports COM object automation.
So in say windows scripting, you could go:
Dim app As Object
Set app = CreateObject("access.application")
app.OpenCurrentDatabase ("path to database")
app.DoCmd.OpenReport ("ReprotName")
app.CloseCurrentDatabase
app.Quit
The above same code would work in vb.net. Note that the “default” to open the report will send it to the printer without preview.
Also keep in mind that since you are creating an instance of the Access application, then all of the startup code and forms will launch and run. If such startup code and the startup form being run requires ANY user interaction, then the above will not work. Because of the above “many” issues, you likely best create an application that has linked tables to the data, and contains your required report. This approach will thus avoid all of the existing application code and startup forms running.
So in any case you WILL have to launch the application and deal with all of the startup forms etc. As noted, often then it makes sense to copy out the report to a separate application with linked tables for your purpose.
Keep also in mind that the Access runtime (as opposed to full version) does not support nor allow use of CreateObject - you have to resort to shell() with startup parameters to launch + run the report.
Last but not least, you can from the Access UI simply DRAG the report to your desktop. The result is a one click button on your desktop that will launch the report in question.

Related

WebView2: Multiple instances of same application need to launch the same browser control

Problem
I recently replaced a System.Windows.Forms.WebBrowser-based control with one that relies on Microsoft.Web.WebView2.WinForms.WebView2 instead. This has been working well, except that my users want to have 2 instances of their application running at once, with both instances occasionally having that WebView2 form open at the same time. When they try this, one of the two instances fails to load the WebView2 control until the other one is closed.
Learned / attempted so far:
I've found WebView2 to be extremely finicky, so I've looked into alternatives like CefSharp, but haven't wanted to dedicate time to implementing them until I know they can solve the problem. So far as I can tell, CefSharp and WebView2 do very similar things as far as launching a Chromium-based browser, rendering to a WinForms control.
This blog post (read: advertisement) for paid alternative DotNetBrowser indicates that
You can initialize and use several Chromium engines simultaneously with different configurations [in DotNetBrowser], which is not possible in CefSharp.
I'm wondering if this same limitation applies to WebView2, and is the cause of my users' inability to have 2 instances of that same form loaded at once.
Context
I'm supporting an ancient desktop CRM that's set to be retired in favor of a modern alternative, but in the mean time, the old standard needs to integrate with new processes we're bringing in. One of those new processes is a web page from an external service that our call center users enter data into, then expect the CRM to pull entered data out of the web page.
The part of their process I did not know about is the 2-instance bit from above: they're used to being able to copy-and-paste from one embedded browser window to the other.
#Poul Bak in the comment on the question had it right: providing settings that differ per-instance of the application fixed the problem.
The setting I changed per-instance was the path of the user data folder: I was able to pass different values for the userDataFolder argument of the CoreWebView2Environment.CreateAsync method, branching based on a variable that holds different values between the instances that my users are running.

Window CE 4.2 - Enumerating through the controls of a different running process

I have been charged with the task to send data from COM 1 to COM 2 in Windows CE 4.2. A running application takes data from COM 1 and displays it to the user in a form (textbox I assume). I then have to take that data and send it out COM 2. COM 1 is being used by the program displaying the data and I know of no way to hijack COM 1.
I figure trying to do a screen scrap would be the next step. Unfortunately this is compact framework and an old version at that and from a lot of research it seems managed code is out of the question . Many of the API functions I would use are not available; FindWindowEx for example.
Here is where I am at now. I have created two projects. One runs with a TextBox and some wording. A separate application runs and tries to read the text in that TextBox. I have been able to find the running process based off the name of the form using FindWindow API. Using code I have found on this site I have even been able to enumerate through the controls of the form. However my TextBox is never found and many of the controls that are found where never placed on the form by myself (listbox, button). I assume those are the form's initial controls.
Does anyone have any experience with this? Currently this is in C# but VB or Visual C++ will be fine. Even if you have any ideas on a third party application. BTW I am not given the option to upgrade to a higher version of compact framework.
Thank you.
An update I just found out about. It does not look like I only screen scrape only new data but instead have to screen scrape the entire screen and send it out COM2. Someone will scan a barcode and I will send out all screen data through COM2. The data may include a picture etc.
For a native C application I have one sceleton that enumerates all child windows and controls inside a dialog: http://code.google.com/p/rdp-auto-login/source/browse/trunk/rdp-auto-login/tscDialog.cpp. See ScanTSCWindow and the results found in the comment "TSC dialog elements".
I started with remote spy and looked thru the RDM window to find the CtrlID values. There is also a nice tool called zDump (http://www.hjgode.de/wp/2009/06/11/zdump-take-a-look-inside-windows-ce/) that runs on device and enables you to look at window elements.
The theory is that every element in Windows (either Mobile or desktop) is a window. Windows are accesible by there window handle. The handle is assign by the OS during CreateWindow/Ex. Inside dialogs, elements can be identified by there control ID (a resource value), the window class (ie "EDIT", "LISTBOX") and window text and internally by the window handle at creation.
The problem with Compact Framework apps is that they hide many of these basics and dialog (Form) elements can not be easily identified from another process.
As you say you are not able to capture COM1, what is, if you stop the application and then open COM1? As knonw, normally on one application can access a serial port at the same time. You can then read the serial data directly and do not need to access a foreign window.
There are also drivers that enable port mirroring or multiple access. Even for Windows CE based OS (ie http://www.virtual-serial-port.org/products/serial-splitter-mobile/).
If the application is a compact framework one you can take a look inside the code using .Net Reflector or similar .Net decompilers. I use that often to mimik or learn from other apps.
You say "I have been charged with the task to send data from COM 1 to COM 2 in Windows CE 4.2. A running application takes data from COM 1 and displays it to the user in a form (textbox I assume). I then have to take that data and send it out COM 2. COM 1 is being used by the program displaying the data and I know of no way to hijack COM 1." and if you do not start the other app you can write your own and do not need to parse the foreign app.
Possibly you can post the other app or more details of what it does what you can not do.
EDIT/UPDATE:
as we now know it is Intermec TE2000 (terminal emulation) the answer is to use the XMLRPC interface provided by TE2000. The interface is able to call back a function hosted by an xmlrpc server and send all screen content (text, fields and attributes) on screen changes. I have working c++ stl windowsce code for that.
If the device is connected via network, the xmlrpc server can even run on a PC.
As TE2000 does use native drwastring API you will not success in reading texts from the window. If you screen capture the window, you will have to do OCR on the image. XMLRPC does avoid all this.
UPDATE2:
I finished a class lib to get async screen updates using TE2000 xmlrpc: see https://github.com/hjgode/ITE_xml_rpc/tree/master/XmlRpcCS/XmlRpcCF
and http://community.intermec.com/t5/Thin-Client-Based-Development/Printing-CV60-Screen-Windows-CE-4-2/m-p/28663/highlight/false#M473

Issue with the window focus in WinRT

I've got an issue with the focus management in WinRT. The issue is specific for the application startup. Let me share the example of it:
If during the startup I change the focus (for instance I can start selecting some text in a browser), the runtime will decide that it doesn't need to show the application. The application is being started in a 'hidden mode'. It means that I do not see the UI, but I still can find it in process explorer.
So what I need here is to make the application be active in all possible cases. I tried to use several native functions such as ShowWindow, SetActiveWindow, SetForegroundWindow, but without any success.
I also noticed that any WinRT app is being started under WWAHOST.exe and mainwindowhandle is 0. The app shows up if I use 'Switch to' option in Process Explorer context menu.
WinRT applications are sandboxed and have very little control on the way the OS handles them, and almost no way to affect the behavior of other applications running on the same host. What I would suggest then is for you to design your application in such a way that it shows some UI as early as possible, then asynchronously you can load any other resources that your application may need.

Prohibit drag&drop from my application into my application

I just implemented drag&drop in my application. It goes two ways:
From my app to Windows Explorer: exports files
From Windows Explorer to my app: imports files
One side effect is that I can also drag files from my application to my application (the same window), which is not intended.
Is there a elegant way to make sure, that a drag&drop operation I started won't be accepted by my application? E.g. check if the source of the drop operation != my application?
You need to register the fact that you initiated a drag from inside your application with some sort of facility or service. If you receive a drop on your application, ask the facility/service if the drag was initiated within your application. If so, discard. Reset the facility/service afterwards (in any case).
I just figured out a way to do this.
Now I set two types of data on my drag&drop data object:
The file names I want to export
A Unicode-Text object containing the name of my application
In my Drop-handler I check if a Unicode-Text object is present and if it contains my application's name. If so, I abort the drop operation.

Setup project with custom form

I’m currently working on a Visual Studio 2010 setup Project and would like to know if the following is possible:
1) Run the setup project in a way that the default forms don’t show, instead I’d show my own custom form that subscribes to setup project events. This way I'd show install messages and increase my own progress bar.
2) If 1 is possible, I would need a way to specify the default location.
3) I have a separate library project, where I have a custom install class (inherits from “System.Configuration.Install.Installer”) from within the install handler I’d like to be able to show custom windows forms, and control choices made by the user. I guess this is possible by adding a reference to system.windows.forms, but would this be the correct way to go about this? If I couldn't hide the default install form, these custom forms would appear over the default install one and I think it would look too great.
Suggestions, links etc appreciated
Thanks!
*UPDATE 1 *
Could I launch an .msi from c# code but also passing in a value.?
Just what this guy does here:
link
But passing in a value... then from my custom install class I take actions depending on this value.
UPDATE 2
Seems like I can:
link code project
UPDATE 3
I'm considering in doing the following, I'll start testing with a winforms app.
1) Launch winforms application.
2) Make a few webService calls, display data, user makes selection.
3) As per link in update 1, launch process(silent mode) and per update 2, pass in selected values.
4) Use some cross process events mechanism (WCF) so that my custom install class can notify my form of the different steps its running and update progress bar and messages.
You can create custom forms but the declaration needs to be done inside MSI. You can show a custom dialog via a custom action but that will not help you much since msi does this:
Load custom action dll
If it is managed the CLR is started and your maanged code executed
When the custom action is left the dll is unloaded and the clr is shut down
This is done every time a custom action is called. This is one of the main reasons why custom actions are normally written in C++.
To be more flexible you should use the WIX toolkit which allows .NET integration as good as it can be with MSI. MSI itself knows nothing about .NET and is a world of its own.
MSI itself defines dialogs and controls inside the msi via tables like the Dialog and Control table.
You could create a dialog and store your state in a msi property between each several msi actions which need to happen e.g. to calculate the disc space for the selected features and so on. But I doubt that this solution will be performant and I fear that starting and shutting down the CLR so often inside one process will expose you to CLR bugs that no one has encountered before.
To set the target location you only need to call the MSI method MsiSetTargetPath which you can PInvoke very easy.
To disable the normal UI you can override it completely or partially vis MsiSetExternalUI but I have not tried to disable only specific dialogs. If you want to hide specific dialogs you should check the msi tables of your current MSI to check if you can set a msi property to make the dialog think it has already been shown.
Yours,
Alois Kraus
As far as I know the setup projects made by Visual Studio are very limited unless you use custom actions. These Custom Actions can take a lot of time to create and debug so it might be wiser to use a more mature/featured tools such as Installshield
EDIT As for showing windows using winforms: that is ok but: a nice setup allows a silent/scripted install, make sure you allow this. Another thing to look out for is machines not having .NET and thus not being able to show the Forms... IMHO that is a no-no unless you are sure .NET (correct version) is present.
EDIT 2 In response to some comments: There are some scenarios that can't be implemented with VISUAL STUDIO Setup and Deployment projects. I am not saying that Windows Installer is bad. E.g., Try to make a custom installer to decide where an application will be installed and skipping the standard window that the project generates. I am not saying that custom actions are limited but they are IMHO not easy either.
Also, when you want use custom WinForms instead of Installer forms you have to make sure that the bootstrap of the .NET framework is done BEFORE showing any (WinForm) windows. It might be possible but if you want such customisation you might be better of with a more flexible tool.

Categories