I am working on the assignment to write a Virtual Printer with C# and NTDDK.
I have created a test printer driver and I am able to print .ps documents(redirected to C:\test\test.ps always) using it. But now I have to write a small application that will popup a messagebox saying "Print is done" using C# but I am not able to figure out how to do it?
Can anyone help me in this?
Thanks in advance!
Use the endprint event...that is something like, in the designer code put:
///////////////
something.EndPrint += new PrintEventHandler(endingclass);
//////////////
in the form constructor, or anywhere in the program/form where you can call the method put:
private void endingclass(object sender, PrintEventArgs e)
{
MessageBox.Show("wazaaaaaaaaaaaaaaaaa");
}
////////
Obviously, you need to make some...arrangements in the code above - but I believe they are self evident. In case you have problems, googl the endprint event, it will 100% has some examples associated with it.
////
On a side note...if you're really bored you can think of asynchronous process which checks the process every....1/10 of a second :). It will work, but it's a bizarre way to accomplish such a thing. Since you're a c++ developer, c# should be easy to you, you'll like it, it's more powerfull than c++ anyway.
Related
I am trying to create a video player in C# using the functions imported from the GStreamer library by Pinvoke. It's looking nice so far, but if I add g_main_loop_run(loop); my C# application freezes and I just can't click any button or move my window.
I think that the problem may involve gmaincontext, but I don't know exactly what the problem is or how to resolve it.
Here is my C++ code in my library:
GstElement *pipeline;
void seek_to_pos(double position) {
gint64 len;
gst_element_query_duration(pipeline, GST_FORMAT_TIME, &len);
gst_element_seek_simple(pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, len*position);
}
void play_file(char* path_to_file, void* hwnd_ptr_of_window){
gst_init(NULL, NULL);
HWND hwnd = (HWND)hwnd_ptr_of_window;
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
pipeline = gst_element_factory_make("playbin", "player");
g_object_set (G_OBJECT (pipeline), "uri", path_to_file, NULL);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(pipeline), (guintptr)hwnd);
gst_element_set_state(pipeline, GST_STATE_PLAYING);
g_main_loop_run(loop);//problem
}
Without the g_main_loop_run(loop); string, all works fine, but of course I need it for some another things.
Also, I already know that I need to run GMainLoop in a
different thread to not block my C# application's event loop but I don't know exactly how I can do it.
So I need a code sample or link which describes how I can do it right. Thanks!
I'm new with C# so go easy on me!
So far - I have a console app that listens for client connections and replies to the client accordingly.
I also have a WPF form with a button and a text box. The button launches some code to connect to the server as a BackgroundWorker, which then waits for a response before appending it to the end of the text box.
This works great, once. Sometimes twice. But then it kept crashing - turns out that the DoWork block wasn't being called at all and it was going straight to RunWorkerCompleted. Of course, the .result is blank so trying to convert it to a string fails.
Is this a rookie mistake? I have tried searching the internet for various ways of saying the above but haven't come across anything useful...
This is the code so far: http://pastebin.com/ZQvCFqxN - there are so many debug outputs from me trying to figure out exactly what went wrong.
This is the result of the debug outputs: http://pastebin.com/V412mppX
Any help much appreciated. Thanks!
EDIT: The relevant code post-fix (thanks to Patrick Quirk below) is:
public void dorequest(string query)
{
request = new BackgroundWorker();
request.WorkerSupportsCancellation = true;
request.WorkerReportsProgress = true;
request.ProgressChanged += request_ProgressChanged;
request.DoWork += request_DoWork;
request.RunWorkerCompleted += request_RunWorkerCompleted;
request.RunWorkerAsync(query);
}
You're attaching your DoWork handler after calling RunWorkerAsync. Flip those around and that should fix it.
Also, in the future please paste code in your question rather than using an external site. And when possible give the smallest amount of code that demonstrates the problem. Makes it easier on us and people who might have the same issue.
I'm trying to create GUI program that generates HTML invoices, and sends them for printing. I have this working. However, now I want to introduce threading.
I have a form with a BackgroundWorker. The Background worker runs this code:
#region BackGroundWorker
private void bg_htmlGeneration_DoWork(object sender, DoWorkEventArgs e)
{
//SOME MORE CODE..
foreach (XElement ele in Lib.GetInvoiceElement(inv, ico.Supplier))
{
PrintDocument(Lib.CreateHTMLFile());
}
}
#endregion
public void PrintDocument(string fileName)
{
var th = new Thread(() =>
{
WebBrowser webBrowserForPrinting = new WebBrowser();
webBrowserForPrinting.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(PrintDocumentHandler);
webBrowserForPrinting.Url = new Uri(fileName);
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
public void PrintDocumentHandler(object sender, WebBrowserDocumentCompletedEventArgs e)
{
((WebBrowser)sender).Print();
((WebBrowser)sender).Dispose();
Application.ExitThread();
}
Everything runs through fine. However, the WebBrowser object refuses to print. There are no errors (that are obvious), the program finishes off with nothing sent to the printer. When I take away the threading, the program works again.
My knowledge of threading is weak, and I'm pretty much teaching myself - so presumably I'm misunderstanding how threading priority is set.
Here's How it should work:
User selects Invoice(s) on Main Form, chooses to print.
Background thread goes away and prints them while user continues on the program.
Any ideas would be appreciated.
Main problem with your code is WebBrowser wrong using.
WebBrowser supposed to be used for interactive web-browsing, during it user do some things in the internet. But in your case you are using WebBrowser just for the printing after downloading the html. This is wrong by two reasons:
Your code creates whole Windows Forms Control and not using even half of its functionality.
Your code tries to use the WinForms Control in the background thread, which leads to the unexpected behaviour.
BackgroundWorker class supposed to be used for
execute a time-consuming operation (like downloads and database transactions) in the background.
Much more:
You must be careful not to manipulate any user-interface objects in your DoWork event handler. Instead, communicate to the user interface through the ProgressChanged and RunWorkerCompleted events.
Your code will fail in the background thread, because WinForms control is a user-interface object.
Just for the record, WebBrowser.Print method invokes native windows API, so you have no chance that this will work in background. From the disassembly code:
this.AxIWebBrowser2.ExecWB(NativeMethods.OLECMDID.OLECMDID_PRINT,
NativeMethods.OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
ref obj,
IntPtr.Zero);
So, my suggestion for your code is:
Remove usage of the WebBrowser class in the background. Use HttpWebRequest instead for downloading the web content.
Choose other way for the printing your downloaded content. Options are:
PrintDocument implementation (example for it is here).
Use MS Office classes for opening and printing your html-files (first parameter for the Print method is a Boolean Background, I think this can help you). As far as I know, even in 2010 this approach works well.
Check other questions about printing (here is a discussion of printing the images, but this is the same thing, I think).
PS: in the comments you've said that you may need the PDF from your html. I did this by C# by two ways:
Batching using the wkhtmltopdf
Using Microsoft Office Add-in: Microsoft Save as PDF or XPS.
This Add-in should be installed on the server, after that you can easily use MS Office classes for saving the output in the PDF format.
Some update here:
As we have an async/await and TPL options for the time-consuming operations, I don't recommend you to use the BackgroundWorker class anymore.
The only good software I know which can decelerate and accelerate the playback of a YouTube video in any browser without first downloading it (because that would be cumbersome), is Enounce MySpeed.
Unfortunately, this software is not free, and my trial version ran out. I was playing around with its registry settings and noticed a few keys:
ProgramsToHook: iexplore.exe;firefox.exe;plugin-container.exe;chrome.exe;safari.exe;opera.exe;maxthon.exe;feeddemon.exe;realplay.exe;flvplayer.exe;flv player.exe;flock.exe;adobe media player.exe
UseFlashAdapter: 1
LLModules: ole32.dll;nspr4.dll;chrome.exe;realplay.exe;objb3201.dll;oleaut32.dll;rpflashplayer.dll
ModulesToIntercept: flash10*;flash9*;npswf32.dll;gcswf32.dll;fldbg10*;flashplayer.3.1.1k.ocx;adobe media player.exe
Based on the names and values of these registry keys, I'm guessing the MySpeed software hooks some function(s) in the listed modules (but modules are or aren't the same as DLLs?..) and does so for each process listed in ProgramsToHook. This is what I don't understand. What is the concept of the MySpeed software. Obviously it's hooking something, but I'm not too familiar with the intricacies of Windows hooks so I came to ask you experts. I'm thinking if I can understand how this hook process works, I can make my own version of the software using EasyHook, which is a fantastic .NET library to perform user-mode and kernel-mode hooks.
I thought that Windows user-mode hooking goes something like this. You choose one function in one DLL, and you intercept that function (a.k.a hook) in one process you want. If you want to hook the DLL in multiple processes, you just have to repeat the procedure for each process.
And then kernel-mode hooking is just choosing one function in one DLL and intercepting that function in every process that calls it (hence kernel-mode). But surely there are tons of ways to hook; I'm not too sure on whats the difference between these two hooks and DLL injection either.
So the point is, I'd like to know how MySpeed works. What is their hooking concept? If I can know this then I can make such a software in .NET!
Thanks in advance.
I can't provide you with an accurate explanation as I don't know the API calls or capabilites, but it goes something like this:
You app looks for iexplore.exe where it intercepts calls to certain modules. The module is mainly flash player. Flash has support for playing the video slower so you modify the call from iexplore.exe (JavaScript play button on webpage) or make an additional call to set playback speed.
What you need to do:
Use this tool to check what is actually happening: http://www.nektra.com/products/deviare-api-hook-windows/
Learn how to ask Flash Player to slow down a video (probably in Flash API docs). One Simple approach could be to see what MySpeed is actually doing using the Deviare API hook tool.
Write a program that replicates this procedure. It involves intercepting messages sent from one handle (iexplore.exe) to another (flash .dll). This can't be done externally, it has to be done internally, so this may be of help: http://www.codeproject.com/KB/threads/winspy.aspx
On hooks: http://msdn.microsoft.com/en-gb/library/ms644960.aspx
I don't think many people has done this in C#, so it could offer a challenge. I would though be interested in the progress (obstacles) if you have a blog or something to share the gory details on. :)
EDIT: The Deviare API Hook software seems not only to spy on calls, but also allow you to intercept them. So its a all-in-one package for your needs. :)
EDIT2: Relevant question: How do I intercept messages being sent to a window?
The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is. This can be accomplished hooking timeGetTime().
This is an extremely easy C# code to accomplish it:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Nektra.Deviare2;
namespace DeviareTest
{
public partial class Form1 : Form
{
private int nSpeed;
private uint nTime;
private NktSpyMgr _spyMgr;
public Form1()
{
InitializeComponent();
_spyMgr = new NktSpyMgr();
_spyMgr.Initialize();
_spyMgr.OnFunctionCalled += new DNktSpyMgrEvents_OnFunctionCalledEventHandler(OnFunctionCalled);
}
private void Form1_Load(object sender, EventArgs e)
{
NktHook hook = _spyMgr.CreateHook("WINMM.dll!timeGetTime", (int)(eNktHookFlags.flgOnlyPostCall));
hook.Hook(true);
bool bProcessFound = false;
NktProcessesEnum enumProcess = _spyMgr.Processes();
NktProcess tempProcess = enumProcess.First();
while (tempProcess != null)
{
if (tempProcess.Name.Equals("iexplore.exe", StringComparison.InvariantCultureIgnoreCase) && tempProcess.PlatformBits == 32)
{
hook.Attach(tempProcess, true);
bProcessFound = true;
}
tempProcess = enumProcess.Next();
}
if(!bProcessFound)
{
MessageBox.Show("Please run \"iexplore.exe\" before!", "Error");
Environment.Exit(0);
}
}
private void OnFunctionCalled(NktHook hook, NktProcess process, NktHookCallInfo hookCallInfo)
{
nTime++;
if (nSpeed==-2)
hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal - (int)(nTime * 0.2);
else if(nSpeed==2)
hookCallInfo.Result().LongVal = hookCallInfo.Result().LongVal + (int)(nTime * 3);
}
private void SlowButton_CheckedChanged(object sender, EventArgs e)
{
nSpeed = -2;
}
private void FastButton_CheckedChanged(object sender, EventArgs e)
{
nSpeed = 2;
}
}
}
I just published an article with a code example showing how to do this with the Deviare hooking engine. The sample code only works with the video part (not audio) and it is available here.
Youtube now has an html5 player with playback speed controls.
All you have to do is enable html5 here http://www.youtube.com/html5
Only some of the videos support the html5 player yet, though.
Hope this helps.
The key to speeding up or slowing down a video is to convince multimedia players that your computer is slower or faster than it really is
manipulating the system time will be a VERY dangerous and idiotic thing to do - not only will you break user-mode threadslices and hence have a serious impact on system-performance but you also will break many logging-functionalities and even user-mode reflectors which control KM-drivers ... this could both crash and physically harm (!) your system because modern hardware is programmable, given the correct (& proprietary, of course) set of func-calls and such. I would highly advise to NOT do reproduce this, even a few AV-apps will intercept this because of its dangerous nature.
But you're somewhat lucky : the kernel uses its own time, synced to hardware so windows itself COULD remain stable for a limited amount of time.
I think you should get back to the drawing-board, manipulating essential structures of your operating-system certainly is not the right way to accomplish your goal.
I'm having trouble with something that I thought would be easy...
I can't get my NotifyIcon to show a balloon tip. The basic code is:
public void ShowSystrayBubble(string msg, int ms)
{
sysTrayIcon.Visible = true;
sysTrayIcon.ShowBalloonTip(20, "Title", "Text", ToolTipIcon.None);
}
Nothing happens when I execute this code. I read that the timeout arg may be in seconds or ms, can't tell, so I tried both and neither works.
I'm using WinXP, .NET 3.5.
I had foiled myself... This turned out to be an issue at the OS level. I had previously disabled all balloons via the registry a few weeks ago.
You can read the information here on how to disable balloon tips in WinXP:
http://support.microsoft.com/kb/307729
To enable them, just set the registry value to 1 instead and logon again/restart.
You should then log the messages for users who have disabled the balloons be able to go review them in case of need. If you can get permissions to read the registry, you could check the value and act accordingly (not to modify the value, but to log or to show the balloon).
Please see this it covers all combinations of mouse clicks with NotifyIcon as well as much more. The code is located in a template and is project setting driven so that you can implement NotifyIcon logic in all your projects with no coding effort at all.
More Here
http://code.msdn.microsoft.com/TheNotifyIconExample