GeckoFX - WinForms - javascript:print() - winforms

i just created a win form app
with a Gecko.GeckoWebBrowser on it
when i navigate to a page with a anchor that has the href attribute set to
javascript:print() and click on it, the print dialog is displayed, but it turns out that when i hit cancel button on that dialog
the Gecko.GeckoWebBrowser is destroyed , i mean the control receives a WM_DETROY message
any clue of what is could be happen here?
how i can prevent it?
i modified the gecko fx Gecko.GeckoWebBrowser windows procedure and catch and bypass that windows message but it seems that is not helping
btw i am using xulrunner-11.0.en-US.win32 and geckofx-11.dll
regards

From looking at the firefox code, It looks like firefox is sending the WM_DESTROY message.
nsPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
{
NS_ENSURE_ARG(parent);
HWND hWnd = GetHWNDForDOMWindow(parent);
NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings);
}
nsresult NativeShowPrintDialog(HWND aHWnd,
nsIWebBrowserPrint* aWebBrowserPrint,
nsIPrintSettings* aPrintSettings)
{
PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings);
nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings);
if (aHWnd) {
::DestroyWindow(aHWnd);
}
return rv;
}
I'm not sure why it would do this.
Some options to fix this:
turn on "print.always_print_silent"
provide and register your own nsIPrintingPromptService
provide and register your own nsIWindowWatcher service.
The nsIWindowWatcher way looks like the proper way to do this looking at GetHWNDForDOMWindow:
HWND
nsPrintingPromptService::GetHWNDForDOMWindow(nsIDOMWindow *aWindow)
{
nsCOMPtr<nsIWebBrowserChrome> chrome;
HWND hWnd = NULL;
// We might be embedded so check this path first
if (mWatcher) {
nsCOMPtr<nsIDOMWindow> fosterParent;
if (!aWindow)
{ // it will be a dependent window. try to find a foster parent.
mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
aWindow = fosterParent;
}
mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
}
if (chrome) {
nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
if (site)
{
HWND w;
site->GetSiteWindow(reinterpret_cast<void **>(&w));
return w;
}
}

Related

WinForms ShowDialog() - No modal dialog box opens

I want to open a dialog as a Login-Box in my Explorer-NamespaceExtension. When I call ShowDialog() the first time the box opens but not as a modal dialog. I can click elements in the Explorer. If I close these dialog and open it again, it is a modal dialog and interaction with the Explorer isn`t possible. Thats what I want to achieve with the first open.
My idea is that I call the form first from the wrong thread. Thats the reason why I used the following code, but it doesn`t solve the problem :/
public delegate void myDelegate();
public void ShowDialogThreadSave()
{
if (this.InvokeRequired)
{
myDelegate d = new myDelegate(ShowDialogThreadSave);
this.Invoke(d);
}
else
{
this.ShowDialog();
}
}
I hope you have an idea :-)
Thanks!
Edit:
The call is fired from a background class. I have 3 possibilities to login into the extension, so i encapsulated the call:
public bool LogIn()
{
bool connected = BackEnd.isConnected();
if(loginDialog == null)
{
LogIn logIn = new LogIn();
}
else
{
if (!connected && !Utils.AlreadyLoggedIn() && !loginDialog.IsAccessible && !loginDialog.Visible)
loginDialog.ShowDialogThreadSave();
else if (!connected && !Utils.AlreadyLoggedIn() && !loginDialog.Visible)
loginDialog.ShowDialogThreadSave();
else if (!connected && !Utils.AlreadyLoggedIn() && loginDialog.Visible)
LOG.DebugFormat("error");
else
Utils.ConnectWithoutLoginWindow();
}
connected = BackEnd.isConnected();
return connected;
}
Edit2: With debugging I found out that the ShowDialogThreadSave() is always called by the UI Thread and I will never use the if... What is the problem?

How would I go about disabling the close button?

First of all, let me get my point for this:
This is an emergency alert system, it pulls from a website which we manipulate in the back office, the program can be minimized but cannot be closed (easily, at least none of the people that will use it will know how). As you can see, if the program was closed the Emergency Alerts wouldn't be seen/heard....that's an issue. I have to deploy this application on over 200 computers so I want it simple, I don't want to create a scheduled task, etc.. to keep it running. I simply want it to not be easy to close.
See my code, below:
/* example.c
This is a Win32 C application (ie, no MFC, WTL, nor even any C++ -- just plain C) that demonstrates
how to embed a browser "control" (actually, an OLE object) in your own window (in order to display a
web page, or an HTML file on disk). The bulk of the OLE/COM code is in DLL.c which creates a DLL that
we use in this simple app. Furthermore, we use LoadLibrary and GetProcAddress, so our DLL is not
actually loaded until/unless we need it.
NOTE: The DLL we create does not normally use UNICODE strings. If you compile this example as UNICODE,
then you should do the same with DLL.C.
*/
#include <windows.h>
#include "..\CWebPage.h" /* Declarations of the functions in DLL.c */
// A running count of how many windows we have open that contain a browser object
unsigned char WindowCount = 0;
// The class name of our Window to host the browser. It can be anything of your choosing.
static const TCHAR ClassName[] = "EAS";
// Where we store the pointers to CWebPage.dll's functions
EmbedBrowserObjectPtr *lpEmbedBrowserObject;
UnEmbedBrowserObjectPtr *lpUnEmbedBrowserObject;
DisplayHTMLPagePtr *lpDisplayHTMLPage;
DisplayHTMLStrPtr *lpDisplayHTMLStr;
/****************************** WindowProc() ***************************
* Our message handler for our window to host the browser.
*/
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_CREATE)
{
// Embed the browser object into our host window. We need do this only
// once. Note that the browser object will start calling some of our
// IOleInPlaceFrame and IOleClientSite functions as soon as we start
// calling browser object functions in EmbedBrowserObject().
if ((*lpEmbedBrowserObject)(hwnd)) return(-1);
// Another window created with an embedded browser object
++WindowCount;
// Success
return(0);
}
if (uMsg == WM_DESTROY)
{
// Detach the browser object from this window, and free resources.
(*lpUnEmbedBrowserObject)(hwnd);
// One less window
--WindowCount;
// If all the windows are now closed, quit this app
if (!WindowCount) PostQuitMessage(0);
return(TRUE);
}
// NOTE: If you want to resize the area that the browser object occupies when you
// resize the window, then handle WM_SIZE and use the IWebBrowser2's put_Width()
// and put_Height() to give it the new dimensions.
return(DefWindowProc(hwnd, uMsg, wParam, lParam));
}
/****************************** WinMain() ***************************
* C program entry point.
*
* This creates a window to host the web browser, and displays a web
* page.
*/
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hInstNULL, LPSTR lpszCmdLine, int nCmdShow)
{
HINSTANCE cwebdll;
MSG msg;
WNDCLASSEX wc;
// Load our DLL containing the OLE/COM code. We do this once-only. It's named "cwebpage.dll"
if ((cwebdll = LoadLibrary("cwebpage.dll")))
{
// Get pointers to the EmbedBrowserObject, DisplayHTMLPage, DisplayHTMLStr, and UnEmbedBrowserObject
// functions, and store them in some globals.
// Get the address of the EmbedBrowserObject() function. NOTE: Only Reginald has this one
lpEmbedBrowserObject = (EmbedBrowserObjectPtr *)GetProcAddress((HINSTANCE)cwebdll, "EmbedBrowserObject");
// Get the address of the UnEmbedBrowserObject() function. NOTE: Only Reginald has this one
lpUnEmbedBrowserObject = (UnEmbedBrowserObjectPtr *)GetProcAddress((HINSTANCE)cwebdll, "UnEmbedBrowserObject");
// Get the address of the DisplayHTMLPagePtr() function
lpDisplayHTMLPage = (DisplayHTMLPagePtr *)GetProcAddress((HINSTANCE)cwebdll, "DisplayHTMLPage");
// Get the address of the DisplayHTMLStr() function
lpDisplayHTMLStr = (DisplayHTMLStrPtr *)GetProcAddress((HINSTANCE)cwebdll, "DisplayHTMLStr");
// Register the class of our window to host the browser. 'WindowProc' is our message handler
// and 'ClassName' is the class name. You can choose any class name you want.
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = &ClassName[0];
RegisterClassEx(&wc);
// Create another window with another browser object embedded in it.
if ((msg.hwnd = CreateWindowEx(0, &ClassName[0], "Emergency Alert System", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
HWND_DESKTOP, NULL, hInstance, 0)))
{
// For this window, display a URL. This could also be a HTML file on disk such as "c:\\myfile.htm".
(*lpDisplayHTMLPage)(msg.hwnd, "http://www.google.com");
// Show the window.
ShowWindow(msg.hwnd, nCmdShow);
UpdateWindow(msg.hwnd);
}
// Do a message loop until WM_QUIT.
while (GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Free the DLL.
FreeLibrary(cwebdll);
return(0);
}
MessageBox(0, "Can't open cwebpage.dll! You are not protected by Emergency Alerting System. Click OK to terminate this application. Contact the developer, Scott Plunkett.", "ERROR", MB_OK);
return(-1);
}
It took this from an example tutorial I found, I have never done any windows programming before so I had to figure out a quick solution.
I appreciate any and all help on this.
If you create a handler for the WM_SYSCOMMAND message and check for the SC_SYSCLOSE parameter, you can stop it from executing the default action of closing the window.
I noticed it's not an MFC application, so you have to call Win32 Library to enable the feature.
Try this out:http://www.davekb.com/browse_programming_tips:win32_disable_close_button:txt
---EDIT---
Sorry the code did not work out. I did not have resources to debug it.
To disable the X of the window, you can either set CS_NOCLOSE property of WNDCLASSEX:
wc.style = CS_NOCLOSE;//in your code
or rewrite the WM_CLOSE message handler function. Thanks.

Using Windows raw_input in NPAPI windowed plugin in Chrome

I have an application which is working fine standalone. It handles all its keyboard/mouse input using raw input. When switching to NPAPI client windowed plugin, I receive inputs via WM_KEYDOWN for keyboard, whereas they're supposed to be disabled by my setup, and worse I do NOT receive any raw input WM_INPUT event for keyboard. Everything else is working, including D3D9 rendering in the window.
Here's how I setup the window roughly (it's quite lengthy):
...
SetWindowLongPtr(Application_hWnd, GWL_WNDPROC, (LONG_PTR)&Application_WndProc);
...
DEV_BROADCAST_DEVICEINTERFACE notificationFilter;
GUID hid = { 0 };
RAWINPUTDEVICE rid[4] = { 0 };
rid[1].usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC (in WDK)
rid[1].usUsage = 0x06; // HID_USAGE_GENERIC_KEYBOARD (in WDK)
rid[1].dwFlags = RIDEV_NOLEGACY;//RIDEV_DEVNOTIFY;
rid[1].hwndTarget = Application_hWnd; // capture only for this window
RegisterRawInputDevices(rid, sizeof(rid) / sizeof(rid[0]), sizeof(rid[0]));
... other raw device detection and related HID stuff
Receiving:
case WM_INPUT:
{
if (GET_RAWINPUT_CODE_WPARAM(wParam) == RIM_INPUT)
{
RAWINPUT raw = { 0 };
UINT dwSize = sizeof(raw);
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER)) > 0)
{
switch (raw.header.dwType)
{
case RIM_TYPEKEYBOARD:
// never reaches here
Error checking is omitted here for clarity, but no error is reported anywhere. Yet it seems to have no effect for keyboard, but I do receive WM_INPUT for mouse.
Anyone has a successfully working raw input keyboard in NPAPI ?
I would try creating your own child HWND inside the one the browser gives you where you'll have more control of what is going on.

Prevent multiple instances of windows

How could I prevent opening multiple windows from a wpf application?
I need to open a window from the menu and if I click to open it again, I want the already opened window to become active.
Any suggestions?
You could use the Application.Current.Windows collection for that. Just check whether this collection contains the window you are about to open and if it does, activate it, otherwise create new window and show it:
var existingWindow = Application.Current.Windows.Cast<Window>().SingleOrDefault(w => /* return "true" if 'w' is the window your are about to open */);
if (existingWindow != null) {
existingWindow.Activate();
}
else {
// Create and show new window
}
Here is one way to do it:
private Window _otherWindow;
private void OpenWindow()
{
if (_otherWindow == null)
{
//Pass in a reference to this window so OtherWindow can call WindowClosed when it is closed..
_otherWindow = new OtherWindow(this);
_otherWindow.Show();
}
else
_otherWindow.Activate(); //Or whatever the method is to bring a window to the front
}
public void WindowClosed()
{
_otherWindow = null;
}

Not able to display the progress bar using threading concept?

I am trying to show a progress bar while my process is going on...in my application there will be a situation where I gotta read files and manipulate them(it will take some time to complete)..want to display a progress bar during this operation..the particular function I am calling is an win 32 ...so if you check my code below ...I am able to display the progressbar but it doesnt show any progress..actually its not doing any further process...Please help me..thanks in advance
//my function
int Myfunction(....)
{
MSG msg;
HWND dialog = CreateWindowEx(0,WC_DIALOG,L"Proccessing...",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
600,300,280,120,NULL,NULL,NULL,NULL);
HWND pBar = CreateWindowEx(NULL,PROGRESS_CLASS,NULL,WS_CHILD|WS_VISIBLE,40,20,200, 20,
dialog,(HMENU)IDD_PROGRESS,NULL,NULL);
SendMessage(pBar,PBM_SETRANGE,0,MAKELPARAM(0,noOfFile));
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
Dispatch(&message);
}
HANDLE getHandle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)SetFilesForOperation(...),
NULL,NULL,0);
}
LPARAM SetFilesForOperation(...)
{
for(int index = 0;index < noOfFiles; index++)
{
*checkstate = *(checkState + index);
if(*checkstate == -1)
{
*(getFiles+i) = new TCHAR[MAX_PATH];
wcscpy(*(getFiles+i),*(dataFiles +index));
i++;
}
else
{
(*tempDataFiles)->Add(*(dataFiles+index));
*(checkState + localIndex) = *(checkState + index);
localIndex++;
}
PostMessage(pBar,PBM_SETPOS,(WPARAM)index,0);
}
}
I suspect the problem is that you're creating the thread after your app exits - if you move the call to CreateThread above the message pump it may work better.
I prefer to use QT over MFC. Here's how I would use it to answer your question:
Use form designer to create a dialog, and use AfxBeginThread(someFunc, param) to create a thread.
In someFunc, use SendMessage to tell the dialog about the progress.
sample here:
http://www.tek-tips.com/faqs.cfm?fid=5162

Resources