ctrl-x, ctrl-v and ctrl-c problems
- From: Frank Buss <fb@xxxxxxxxxxxxx>
- Date: Tue, 5 Jul 2005 10:52:37 +0200
I've writte a small program (see below), which embeds the webbrowser
control in a window. You can download the full project at
http://www.frank-buss.de/tmp/test.zip
The problem is, that the Ctrl-accelerator keys didn't work, for example for
this page: http://www.frank-buss.de/tmp/form.html
I've tried the workaround from
http://www.microsoft.com/mind/0499/faq/faq0499.asp :
Adding a new message handler:
MESSAGE_HANDLER( WM_KEYDOWN, OnKeydown )
LRESULT OnKeydown(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
CComQIPtr<IOleInPlaceActiveObject,
&IID_IOleInPlaceActiveObject> pIOIPAO(m_spBrowser);
HRESULT hr = S_FALSE;
if (pIOIPAO)
{
MSG msg;
msg.message = uMsg;
msg.wParam = wParam;
msg.lParam = lParam;
hr = pIOIPAO->TranslateAccelerator(&msg);
}
return 0;
}
but doesn't work, because the "Sometimes your application will not
automatically be sent WM_KEYDOWN messages for accelerator keys. " from the
FAQ applies, so I changed my message loop, too:
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage(&msg);
if (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) {
::SendMessage(atlWnd, msg.message, msg.wParam, msg.lParam);
}
DispatchMessage(&msg);
}
Now I can use ctrl-c, ctrl-x and ctrl-v with the form.html sample, but when
I try to select text by holding down the shift-key and moving with the
cursor keys, it selects two chars at once.
The other problem is, when I try to use the accelerators in a Flash movie,
for example this one: http://www.frank-buss.de/tmp/flash.html .
Selecting with holding the shift key down works, but looks like ctrl-v
appends some garbage after the clipboard data, and ctrl-c and ctrl-x
substitutes the selected text with garbage.
Both work from Internet Explorer without problems. I want the same
behaviour in my program.
The source, without the Microsoft FAQ hack:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <string>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
#include <comutil.h>
using namespace ATL;
using namespace std;
extern string wget(string host, string url);
int winWidth=800;
int winHeight=410;
const char* title = "Test";
CComModule _Module;
#define CHECK_HR(hr) if ( FAILED(hr) ) ATLTRACE( _T("FAILED! HR =
0x%08x\n"), hr )
#define RETURN_FAILED(hr) CHECK_HR(hr); if ( FAILED(hr) ) return hr
///////////////////////////////////////////////////////////////////////////////////////
// GetHTML - Takes an HTMLDocument2 object, and gets the HTML source code
// for it
// The caller is responsible for freeing the memory allocated
///////////////////////////////////////////////////////////////////////////////////////
HRESULT GetHTML( IHTMLDocument2* pDoc, LPSTR& lpData, DWORD& dwSize )
{
HRESULT hr;
CComPtr<IPersistStreamInit> spPersist;
CComPtr<IStream> spStream;
HGLOBAL hGlobal;
STATSTG stgstats;
LPVOID lpRawData;
// Get the right interface
hr = pDoc->QueryInterface( &spPersist );
RETURN_FAILED( hr );
// Create the stream object
hr = ::CreateStreamOnHGlobal( NULL, TRUE, &spStream );
RETURN_FAILED( hr );
// Save the HTML
hr = spPersist->Save( spStream, FALSE );
RETURN_FAILED( hr );
// Get the size of the stream
hr = spStream->Stat( &stgstats, STATFLAG_NONAME );
RETURN_FAILED( hr );
// Get the global memory
hr = ::GetHGlobalFromStream( spStream, &hGlobal );
RETURN_FAILED( hr );
lpRawData = ::GlobalLock(hGlobal);
if ( lpRawData != NULL )
{
dwSize = stgstats.cbSize.LowPart + 1;
lpData = new char[dwSize];
ZeroMemory( lpData, dwSize );
CopyMemory( lpData, lpRawData, dwSize-1 );
::GlobalUnlock( hGlobal );
hr = S_OK;
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
string url = "http://www.frank-buss.de/tmp/form.html";
class CWebWindow : public CWindowImpl<CWebWindow>
{
// START MESSAGE_MAP
BEGIN_MSG_MAP( CWebWindow )
MESSAGE_HANDLER( WM_CREATE, OnCreate )
MESSAGE_HANDLER( WM_CREATE, OnCreate )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER( WM_KEYDOWN, OnKeydown )
END_MSG_MAP()
// END MESSAGE_MAP
LRESULT OnKeydown(UINT uMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
CComQIPtr<IOleInPlaceActiveObject,
&IID_IOleInPlaceActiveObject> pIOIPAO(m_spBrowser);
HRESULT hr = S_FALSE;
if (pIOIPAO)
{
MSG msg;
msg.message = uMsg;
msg.wParam = wParam;
msg.lParam = lParam;
hr = pIOIPAO->TranslateAccelerator(&msg);
}
return 0;
}
LRESULT OnCreate( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/,
BOOL& /*bHandled*/ )
{
HRESULT hr;
RECT cr;
GetClientRect(&cr);
int dx = winWidth - (cr.right-cr.left);
int dy = winHeight - (cr.bottom-cr.top);
int breite = GetSystemMetrics(SM_CXSCREEN);
int hoehe = GetSystemMetrics(SM_CYSCREEN);
int px = breite/2-((winWidth+dx)/2)-5;
int py = hoehe/2-((winHeight+dy)/2)-5;
MoveWindow(px, py, winWidth + dx, winHeight + dy);
GetClientRect(&cr);
m_wndAx.Create( m_hWnd, cr, NULL, WS_CHILD|WS_VISIBLE);
hr = m_wndAx.CreateControl( _bstr_t(url.c_str()) );
CHECK_HR( hr );
if ( SUCCEEDED(hr) )
{
hr = m_wndAx.QueryControl( IID_IWebBrowser2, (void**)&m_spBrowser );
CHECK_HR( hr );
ShowHTML();
} else {
::MessageBox(NULL, "Fehler beim Starten des Internet Explorers.\nBitte installieren Sie eine aktuelle Internet Explorer Version.", title, MB_ICONWARNING);
}
return SUCCEEDED(hr) ? 0 : -1;
}
LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& )
{
PostQuitMessage( 0 );
return 0;
}
HRESULT ShowHTML()
{
HRESULT hr;
CComPtr<IDispatch> spDocDispatch;
CComPtr<IHTMLDocument2> spDocument;
READYSTATE rs;
MSG msg;
LPSTR lpData;
DWORD dwSize;
// Wait for the page to finish loading
do
{
hr = m_spBrowser->get_ReadyState( &rs );
RETURN_FAILED( hr );
if ( rs != READYSTATE_COMPLETE )
{
if ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
} while ( rs != READYSTATE_COMPLETE );
hr = m_spBrowser->get_Document( &spDocDispatch );
RETURN_FAILED( hr );
hr = spDocDispatch->QueryInterface( &spDocument );
RETURN_FAILED( hr );
// Call the main function
hr = GetHTML( spDocument, lpData, dwSize );
RETURN_FAILED( hr );
// Display the HTML
//::OutputDebugString( lpData );
//::MessageBoxA( m_hWnd, lpData, "HTML Display", MB_OK );
delete [] lpData;
return S_OK;
}
private:
CComPtr<IWebBrowser2> m_spBrowser;
CAxWindow m_wndAx;
};
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
::CoInitialize( NULL );
_Module.Init(NULL, hInstance, &LIBID_ATLLib);
// Create an instance of CWebWindow
CWebWindow atlWnd;
int breite = GetSystemMetrics(SM_CXSCREEN);
int hoehe = GetSystemMetrics(SM_CYSCREEN);
int px = breite/2-(winWidth/2)-5;
int py = hoehe/2-(winHeight/2)-5;
RECT wr;
wr.left = px;
wr.top = py;
wr.right = winWidth + wr.left;
wr.bottom = winHeight + wr.top;
atlWnd.Create( NULL, wr, title, WS_TILED | WS_VISIBLE | WS_SYSMENU);
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
exit(0);
}
--
Frank Buß, fb@xxxxxxxxxxxxx
http://www.frank-buss.de, http://www.it4-systems.de
.
- Follow-Ups:
- Re: ctrl-x, ctrl-v and ctrl-c problems
- From: Igor Tandetnik
- Re: ctrl-x, ctrl-v and ctrl-c problems
- Prev by Date: Re: Using webbrowser to parse html
- Next by Date: axWebBrowser - occasional SocketException when clicking back/forward under .NET 1.1
- Previous by thread: Re: Detect if a new window has been spawn by a user click or not
- Next by thread: Re: ctrl-x, ctrl-v and ctrl-c problems
- Index(es):