x
This website is using cookies. We use cookies to ensure that we give you the best experience on our website. More info. That's Fine
HPC:Factor Logo 
 
Latest Forum Activity

Microsoft HTML Control

cyranoses
cyranoses Page Icon Posted 2004-11-15 8:48 PM
#
Status:
Has anyone done any programming using the HTML Control. I am trying to build dll that utilizes it. If you don't mind some dialog on the subject let me know.
 Top of the page
ncchang Page Icon Posted 2004-11-15 10:17 PM
#
Avatar image of ncchang
Factorite (Junior)

Posts:
34
Status:
kinda helps if you post the question
or describe what you wanna discuss

:)


good reference is
http://pocketpcdn.com/sections/html.html

assuming you are coding in C or maybe C++

nathan
 Top of the page
chiark Page Icon Posted 2004-11-16 2:51 AM
#
Avatar image of chiark
H/PC Sensei

Posts:
1,330
Location:
North of England
Status:
What is it you want to know
Cheers,
nick.
 Top of the page
cyranoses
cyranoses Page Icon Posted 2004-11-16 1:14 PM
#
Status:
I am coding a dll in evc++ to use in an evb app for my Jornada 720. I know way more about evb than c++ so I am basically trying to use available open source to code the dll. I have declared a CComModule and initialized it with a htmlview window using the DISPLAYCLASS of the htmlview.dll. I set up a message handler for WM_NOTIFY and that works beautifully for the NM_HOTSPOT message. I have successfully coded some properties and methods that work fine. I have even managed to write a custom event that successfully executes in my vb app. My problem is that I don't seem to be able to trap some other much needed messages from my vb app. I would like to get the mouse coordinates when the stylus taps on the HTML viewer window. I tried setting up a message handler for WM_LBUTTONUP but this message does not seem to be coming into my dll. I also tried to test for NM_CLICK in my WM_NOTIFY handler but this doesn't seem to be coming to the dll either. If I haven't explained clearly, please give me another chance. Do you have any suggestions? Thanks in advance.
 Top of the page
chiark Page Icon Posted 2004-11-16 4:10 PM
#
Avatar image of chiark
H/PC Sensei

Posts:
1,330
Location:
North of England
Status:
The problem is that the messages need to be processed by the control for the control to work properly. I'm having a bit of a nightmare with my PC right now, as I've had to reinstall everything, but I'll have a look tomorrow.

To get this straight: you've got a VB application, and you want the DLL to "raise an event" which gives the coordinates of where the stylus left the screen which can be trapped by the VB app?

Cheers,
Nick.
 Top of the page
cyranoses
cyranoses Page Icon Posted 2004-11-16 9:23 PM
#
Status:
Yes, that is pretty much what I want to do. If I could get the coordinates of where the stylus left the screen sent straight to the dll as soon as the stylus leaves the screen, I would be set. Once I get those coordinates to the dll, I can raise the event in the vb app. Now when I created activex controls in vb, you could trap the intrinsic events of the composite controls that make up your custom control. That is if the text changes in a textbox you can make a textchanged event for your control that just calls the textchanged method of the composite textbox and voila, when a user types in the textbox, the event triggers. I know that I am not making a genuine activex here but isn't the principle the same? In my vb app I put the viewer (created by the dll) on a form. If i tap the stylus on the form, the form gets a mouseclick event. If I tap the stylus on a LINK in the html viewer, a hotspot message gets sent to the dll along with the href target so the viewer window can display the link. If I tap the stylus randomly on the html viewer window, I don't know what happens. I hear a system click sound so I know some message gets passed to make the sound happen. The problem with the html viewer control is that I am not sure it has an intrinsic way to capture a mouse click other than the hotspot message. If it did, would not the mouseclick message pass to the dll in the same way that the hotspot message does? If Microsoft's viewer doesn't instrinsicly process a mouseclick, then I need a way to get the mouse coordinates from the vb app itself, something I dont know how to do in vb or c++. Then I need to let the dll know a tap event has occurred and pass the dll the coordinates of the stylus tap. In fact, it has occurred to me that if I could get the mouse coordinates from within my vbapp I could just use sendmessage to get the info to the dll. The message handler in the dll would execute when the message came in and I could trigger my event there. I just dont know how to get those mouse coordinates.
 Top of the page
ncchang Page Icon Posted 2004-11-17 1:37 AM
#
Avatar image of ncchang
Factorite (Junior)

Posts:
34
Status:
hmm. you could not catch the wm_lbuttonup message.
That is strange.

Could you post some of the dll code that
handles the messages ?

Not sure which tool you are using but
if you have remote SPY++ installed(comes with embedded visual tool 3.0)
you can monitor the controls and see what messages it
is receiving.

But you should really check out the example
here (can be found on the pocketpcdn.com site)
http://www.devbuzz.com/content/zinc_eVB_html_viewer_ctrl_pg1.asp
and
http://www.devbuzz.com/content/zinc_eVB_html_viewer_ctrl_II_pg1.asp

I think that might be in line with what you are trying to do.

sorry cant be more help since I am not too familiar with VB

Note: Just because the code is written for the pockect pc platform,
it does not mean the code would not work on other platforms.
The pockect pc forums/help sites can be a great reference
for code help. But keep in mind not all API/Messages/Structures/
Libraries are available on all platforms.


Nathan
 Top of the page
cyranoses
cyranoses Page Icon Posted 2004-11-18 12:18 PM
#
Status:
here is part of my header file. Everything works except the buttonup message: I do not know what the little smirky faces mean. There is a close parenthesis where each of the icons appear. What is the correct syntax?

// HTMLViewer.h : Declaration of the CHTMLViewer

#ifndef __HTMLVIEWER_H_
#define __HTMLVIEWER_H_

#include "resource.h" // main symbols
#include "VOImage.h"
#include <Atlbase.h>
#include <atlctl.h>
#include <htmlctrl.h>
#include<comdef.h> //for bstr conversion
#include<atlconv.h> //for uses conversion t2bstr
#include <stdlib.h> //for conversion
#include "HTMLControlCP.h"

/////////////////////////////////////////////////////////////////////////////
// CHTMLViewer
class ATL_NO_VTABLE CHTMLViewer :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatchImpl<IHTMLViewer, &IID_IHTMLViewer, &LIBID_HTMLCONTROLLib>,
public CComControl<CHTMLViewer>,
public IPersistStreamInitImpl<CHTMLViewer>,
public IOleControlImpl<CHTMLViewer>,
public IOleObjectImpl<CHTMLViewer>,
public IOleInPlaceActiveObjectImpl<CHTMLViewer>,
public IViewObjectExImpl<CHTMLViewer>,
public IOleInPlaceObjectWindowlessImpl<CHTMLViewer>,
public IConnectionPointContainerImpl<CHTMLViewer>,
public IPersistStorageImpl<CHTMLViewer>,
public ISpecifyPropertyPagesImpl<CHTMLViewer>,
public IQuickActivateImpl<CHTMLViewer>,
public IDataObjectImpl<CHTMLViewer>,
public IProvideClassInfo2Impl<&CLSID_HTMLViewer, &DIID__IHTMLViewerEvents, &LIBID_HTMLCONTROLLib>,
public IPropertyNotifySinkCP<CHTMLViewer>,
public CComCoClass<CHTMLViewer, &CLSID_HTMLViewer>,
public CProxy_IHTMLViewerEvents<CHTMLViewer>
{
public:
CHTMLViewer() : m_ctlHTMLViewer(_T("DISPLAYCLASS", this, 1)
{
m_bWindowOnly = TRUE;

}

DECLARE_REGISTRY_RESOURCEID(IDR_HTMLVIEWER)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CHTMLViewer)
COM_INTERFACE_ENTRY(IHTMLViewer)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) //I added
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
COM_INTERFACE_ENTRY(IQuickActivate)
COM_INTERFACE_ENTRY(IPersistStorage)
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IProvideClassInfo)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
END_COM_MAP()

BEGIN_PROP_MAP(CHTMLViewer)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
//PROP_ENTRY("BorderVisible", DISPID_BORDERVISIBLE, CLSID_NULL)
// Example entries
// PROP_ENTRY("Property Description", dispid, clsid)
// PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()



BEGIN_CONNECTION_POINT_MAP(CHTMLViewer)
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
CONNECTION_POINT_ENTRY(DIID__IHTMLViewerEvents)
//CONNECTION_POINT_ENTRY(IID__IHTMLViewerEvents)
// CONNECTION_POINT_ENTRY(IID__IHTMLViewerEvents)
END_CONNECTION_POINT_MAP()


BEGIN_MSG_MAP(CHTMLViewer)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
CHAIN_MSG_MAP(CComControl<CHTMLViewer>
ALT_MSG_MAP(1)
// Replace this with message map entries for superclassed ListBox
END_MSG_MAP()
// Handler prototypes:
// LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
// LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
// LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

BOOL PreTranslateAccelerator(LPMSG pMsg, HRESULT& hRet)
{
if(pMsg->message == WM_KEYDOWN &&
(pMsg->wParam == VK_LEFT ||
pMsg->wParam == VK_RIGHT ||
pMsg->wParam == VK_UP ||
pMsg->wParam == VK_DOWN))
{
hRet = S_FALSE;
return TRUE;
}
//TODO: Add your additional accelerator handling code here

return FALSE;
}

//THIS WORKS
LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
LRESULT lRes = CComControl<CHTMLViewer>:: OnSetFocus(uMsg, wParam, lParam, bHandled);
if (m_bInPlaceActive)
{
DoVerbUIActivate(&m_rcPos, NULL);
if(!IsChild(::GetFocus()))
{
m_ctlHTMLViewer.SetFocus();
}
}
return lRes;
}

//THIS WORKS
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
RECT rc;
LoadLibrary (_T("htmlview.dll");
InitHTMLControl(_Module.m_hInst);
GetWindowRect(&rc);
rc.right -= rc.left;
rc.bottom -= rc.top;
rc.top = rc.left = 0;
m_ctlHTMLViewer.Create(m_hWnd, rc, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER);
return 0;
}

//This is the WM_NOTIFY HANDLER. IT WORKS
LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

NM_HTMLVIEW* pnm = (NM_HTMLVIEW*)lParam;
LPNMHDR pnmh = (LPNMHDR) &(pnm->hdr);
switch(pnmh->code)
{

//----------------------------------------------------------------------------
//This notification message is sent by the Windows HTML viewer control when the
//user taps on a link or submits a form.
//----------------------------------------------------------------------------
case NM_HOTSPOT:
{
//this code successfully causes the LinkSelect Event
//to fire in my vb app so I know the wm_notify handler
//works.
USES_CONVERSION;
LPTSTR temp;
temp=(LPTSTR)(pnm->szTarget);
g_StrongsNumber=T2BSTR(temp);
Fire_LinkSelect(1,1,2);

break;
}
}
return 0;
} // end OnNotify

//THis is the WM_LBUTTONUP HANDLER. DOES NOT WORK
LRESULT OnLButtonUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
// If the message is received an event will fire in my vb app, but it
//doesn't fir
Fire_LinkSelect(1,1,2);
return 0;
}


//tHERE IS MORE BUT i DID NOT INCLUDE.....
};

#endif //__HTMLVIEWER_H_
 Top of the page
chiark Page Icon Posted 2004-11-18 3:42 PM
#
Avatar image of chiark
H/PC Sensei

Posts:
1,330
Location:
North of England
Status:
Right, I think I see what you're doing, and where it's going wrong.

The code you've got there creates a window, then creates a child window of class HTMLView using the code in the HTMLView dll which happens to fill the whole parent.

Your message handler, and this is the important bit, is for the parent window. ie, your code traps SETFOCUS, which is setting focus onto your window (not the HTMLView window - presumably that passes it through the chain...)

It also traps WM_NOTIFY, which is how your child window speaks to a parent window.

In short, the problem is that you are trying to trap the WM_LBUTTONUP event on your DLL's *main* window, which is the parent window of the HTMLView window. You won't get this message because it is "consumed" by the HTMLView child window, which acts on it in order to raise the WM_NOTIFY back to your parent window.

What you need to do is replace the WndProc (windows message processor) of your HTMLView window. To do this, call SetWindowLong (with the hwnd of the HTMLView window) to replace the wndproc with one of your own devising, and store the returned value as that's the original WndProc of the window.

Your new wndproc will be a standard wndproc, but you'll switch on the message type (look for WM_LBUTTONUP) and fire your event. You *must* then pass all events (including the one you look for) through to the original WndProc. Do this using the CallWindowProc call.

So, look up SetWindowLong and CallWindowProc and you're laughing.

I'm afraid I don't know how to do this in MFC, but there's probably some information on the net. You're basically subclassing a htmlview window. Google for <I>subclassing mfc wndproc setwindowlong callwindowproc</I> and you should get something to be going on with

Hope that gives you what you need!

Cheers,
Nick.
 Top of the page
cyranoses
cyranoses Page Icon Posted 2004-11-21 5:51 PM
#
Status:
I have been reading about subclassing as you suggested.
I used this article from the CodeGuru site as a reference:
http://www.codeguru.com/Cpp/COM-Tech/atl/print.php/c3605/
See the section under message maps.

According to the above my contained window superclasses the Microsoft html control in the following 2 lines of code

CHTMLViewer() : m_ctlHTMLViewer(_T("DISPLAYCLASS", this, 1)

and

m_ctlHTMLViewer.Create(m_hWnd, rc, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER);

where
m_ctlHTMLViewer is a CContainedWindow

BEGIN_MSG_MAP handles the messages for the parent container
and
BEGIN_ALT_MSG_MAP(1) handles the messages for the superclassed htmlviewer

I tried putting this line in the alternate message map
BEGIN_ALT_MSG_MAP(1)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)

the OnLButtonUp routine never fires contrary to the CodeGuru's assertion.

I could not find any documentation or forum links that show how to subclass the messages of a superclassed window but I tried anyway. I added these lines to the OnCreate routine where I create the superclassed child window.(code listed in previous forum message)

m_ctlHTMLViewer.Create(.....)
g_Viewerhwnd=(HWND)FindWindow(_T("DISPLAYCLASS"), NULL);
g_OldViewer = (WNDPROC)(SetWindowLong(g_Viewerhwnd, GWL_WNDPROC, (LONG)NewViewerProc));
where the following 2 variables are declared as public
HWND g_Viewerhwnd
WNDPROC g_OldViewer

The compiler crashes on the SetWindowLong line with the following 2 errors

error C2440: 'type cast' : cannot convert from 'long (__cdecl CHTMLViewer::*)(struct HWND__ *,unsigned int,unsigned int,long,int &)' to 'long'
Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast

error C2660: 'SetWindowLongW' : function does not take 3 parameters

I tried using static_cast on every part of that line to no avail. The last error obviously has nothing to do with the number of parameters as 3 is correct.
Do you think I just have a syntax error, or is the whole effort doomed?
 Top of the page
chiark Page Icon Posted 2004-11-22 12:48 PM
#
Avatar image of chiark
H/PC Sensei

Posts:
1,330
Location:
North of England
Status:
The compiler is complaining about the declaration of NewViewerProc that you're passing it.

First off, I know nothing of any signficance about MFC. I don't like it for exactly this reason - the abstraction makes playing with stuff more complex . But then again, I'm happiest with C and Win API calls...

I do not know how to do what you want in MFC, so you've got a choice: either try to understand what MFC is doing, and do it that way, or make a dirty hack.

From looking at it, you're getting confused (or I am) between the hwnds that are floating around. Every control is actually a window within Windows, and has a handle associated with it, as well as a wndproc. It's the wndproc of the HTML Viewer that you need to replace, not that of the parent window.

- you need to get the HWND of the created control, which is a member of the ccomcontrol class called "m_hWndCD". So gViewerHwnd= m_ctlHTMLViewer.m_hWndCD
- you need to declare NewViewerProc with the right prototype. It looks currently like it's a private member function of your class, and you don't really want it to be. You want a plain, vanilla style C function. If you show us the prototype for NewViewerProc, it might help


Cheers,
Nick.
 Top of the page
Jump to forum:
Seconds to generate: 0.171 - Cached queries : 62 - Executed queries : 10