Solved

Problems implimenting a feature

Posted on 2006-11-14
18
880 Views
Last Modified: 2013-11-20
Hi guys,

I've taken this code, and made some changes to it to suite my needs (added a few functions, and changed a few existing functions):

http://www.codeproject.com/internet/CustomBrowser.asp


Works fine. I now want to add the features found here:

http://www.codeproject.com/com/jscalls.asp

Into the same project, but not having much luck, could somebody kindly guide me into implimenting it into my code, and letting me know what I need to call to make JavaScript calls? Is it just:

m_webPage.CallJScript("MyFunction");

Or do I need to make pre-declarations first?


All help is appreciated!

Cheers guys 'n gals!
0
Comment
Question by:Cyber-Drugs
  • 9
  • 9
18 Comments
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
>>could somebody kindly guide me into implimenting it into my code, and letting me know what I need to call to make JavaScript calls?

Have you looked at how function CallJScript() implemented and tried to include same in your project ?

CComVariant CWebPage::CallJScript(const CString strFunc,const CStringArray& paramArray)
{
  //Getting IDispatch for Java Script objects
  CComPtr<IDispatch> spScript;
  if(!GetJScript(spScript))
  {
    ShowError("Cannot GetScript");
    return false;
  }
  //Find dispid for given function in the object
  CComBSTR bstrMember(strFunc);
  DISPID dispid = NULL;
  HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1,LOCALE_SYSTEM_DEFAULT,&dispid);
  if(FAILED(hr))
  {
    ShowError(GetSystemErrorMessage(hr));
    return false;
  }
 
  const int arraySize = paramArray.GetSize();
  //Putting parameters  
  DISPPARAMS dispparams;
  memset(&dispparams, 0, sizeof dispparams);
  dispparams.cArgs      = arraySize;
  dispparams.rgvarg     = new VARIANT[dispparams.cArgs];
  dispparams.cNamedArgs = 0;
 
  for( int i = 0; i < arraySize; i++)
  {
    CComBSTR bstr = paramArray.GetAt(arraySize - 1 - i); // back reading
    bstr.CopyTo(&dispparams.rgvarg[i].bstrVal);
    dispparams.rgvarg[i].vt = VT_BSTR;
  }
  EXCEPINFO excepInfo;
  memset(&excepInfo, 0, sizeof excepInfo);
  CComVariant vaResult;
  UINT nArgErr = (UINT)-1;  // initialize to invalid arg
  //Call JavaScript function        
  hr = spScript->Invoke(dispid,IID_NULL,0,  DISPATCH_METHOD,&dispparams,  &vaResult,&excepInfo,&nArgErr);
  delete [] dispparams.rgvarg;
  if(FAILED(hr))
  {
    ShowError(GetSystemErrorMessage(hr));
    return false;
  }
  return vaResult;
}

Have a look at class implementations CWebPage and CWebPage::CallJScript() srccode.

-MAHESH
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
However following is a simple KB article for you to refer regarding this :

How To Call a Script Function from a VC WebBrowser Application
http://support.microsoft.com/kb/q185127/ <=====

-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
mahesh1402,

I checked out that link you sent me, not sure which to choose. Which one of the two would you recommend? I'll try to impliment it, and then tell you what issues I get (if any).


Cheers!
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
As I said KB article will be easy to implement in your existing workspace..

How To Call a Script Function from a VC WebBrowser Application
http://support.microsoft.com/kb/q185127/ <=====

-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
I'm not quite sure what this is, is it required?

#import "C:\winnt\system32\mshtml.tlb" // location of mshtml.tlb


If I wanted it to call functions dynamically, would I change it to look like this?


   void CMyClass::ExecuteScriptFunction(LPARAM strFunction)
   {
      // m_WebBrowser is an instance of IWebBrowser2
      MSHTML::IHTMLDocument2Ptr spDoc(m_WebBrowser.GetDocument());

      if (spDoc)
      {
         IDispatchPtr spDisp(spDoc->GetScript());
         if (spDisp)
         {
            // Evaluate is the name of the script function.
            OLECHAR FAR* szMember = strFunction;
            DISPID dispid;

            HRESULT hr = spDisp->GetIDsOfNames(IID_NULL, &szMember, 1,
                                           LOCALE_SYSTEM_DEFAULT, &dispid);

            if (SUCCEEDED(hr))
            {
               COleVariant vtResult;
               static BYTE parms[] = VTS_BSTR;

               COleDispatchDriver dispDriver(spDisp, FALSE);

               dispDriver.InvokeHelper(dispid, DISPATCH_METHOD, VT_VARIANT,
                                       (void*)&vtResult, parms,
                                       "5+Math.sin(9)");
            }
         }
      }
   }


and make use of it like this?

CMyClass::ExecuteScriptFunction(myFunctionNameHere);


Cheers!
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
NO its not necessary to #import "C:\winnt\system32\mshtml.tlb" ....

use it like :

CMyClass objMyClass;

objMyClass.ExecuteScriptFunction(myFunctionNameHere);


-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
mahesh1402,

OK, I've only got one last problem... I think it's possibly from me missing something out, but I'm getting this error when I try compile:

fatal error C1010: unexpected end of file while looking for precompiled header directive

Which points to the last "}" in the function.



Cheers!
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
I think you need to set 'Not using the precompiled headers' under Project->Settings->C/C++,
choose Category  'Precompiled Headers' and check Not using the precompiled headers..

Otherwise
you may need to add

#include "StdAfx.h"

as the 1st line of your source file(s).

-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
The first one left me with these 7:

\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(3) : error C2653: 'CMyClass' : is not a class or namespace name
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(3) : error C2065: 'LPARAM' : undeclared identifier
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(3) : error C2146: syntax error : missing ')' before identifier 'strFunction'
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(3) : error C2182: 'ExecuteScriptFunction' : illegal use of type 'void'
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(3) : error C2059: syntax error : ')'
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(4) : error C2143: syntax error : missing ';' before '{'
\\hq-server\user docs\justinn\my documents\custombrowser\custombrowserjs.cpp(4) : error C2447: missing function header (old-style formal list?)


The second one left me with these 13:

\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(3) : error C2653: 'CMyClass' : is not a class or namespace name
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2653: 'MSHTML' : is not a class or namespace name
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2065: 'IHTMLDocument2Ptr' : undeclared identifier
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2146: syntax error : missing ';' before identifier 'spDoc'
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2065: 'spDoc' : undeclared identifier
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2065: 'm_WebBrowser' : undeclared identifier
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(6) : error C2228: left of '.GetDocument' must have class/struct/union type
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(10) : error C2065: 'IDispatchPtr' : undeclared identifier
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(10) : error C2146: syntax error : missing ';' before identifier 'spDisp'
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(10) : error C2065: 'spDisp' : undeclared identifier
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(10) : error C2227: left of '->GetScript' must point to class/struct/union
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(14) : error C2440: 'initializing' : cannot convert from 'long' to 'unsigned short *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
\\Hq-server\User Docs\JustinN\My Documents\CustomBrowser\CustomBrowserJS.cpp(17) : error C2227: left of '->GetIDsOfNames' must point to class/struct/union
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
probably you need

#include "stdafx.h"

-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
mahesh1402,
The 13 errors above are what occur when I include the stdafx.h file mentioned.
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
mahesh1402,
Would it help at all if I uploaded the project to www.ee-stuff.com and pasted a link here?
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
ok !
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
0
 
LVL 22

Expert Comment

by:mahesh1402
Comment Utility
cyber-drugs
you missed \res folder in your project 's zip file.
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
0
 
LVL 22

Accepted Solution

by:
mahesh1402 earned 500 total points
Comment Utility
cyber-drugs

instead of creating a new file like CustomBrowserJS.CPP just add this function as member of existing class...

for example open CustomModalDialog.cpp and just define it like

#import "C:\\windows\\system32\mshtml.tlb"   // **you need this !

void CCustomModalDialog::ExecuteScriptFunction()
{
  // m_WebBrowser is an instance of IWebBrowser2
  MSHTML::IHTMLDocument2Ptr spDoc(m_browser.GetDocument());

  if (spDoc)
  {
     IDispatchPtr spDisp(spDoc->GetScript());
     if (spDisp)
     {
        // Evaluate is the name of the script function.
            
        OLECHAR FAR* szMember = L"evaluate";
        DISPID dispid;

        HRESULT hr = spDisp->GetIDsOfNames(IID_NULL, &szMember, 1,
                                       LOCALE_SYSTEM_DEFAULT, &dispid);

        if (SUCCEEDED(hr))
        {
           COleVariant vtResult;
           static BYTE parms[] = VTS_BSTR;

           COleDispatchDriver dispDriver(spDisp, FALSE);

           dispDriver.InvokeHelper(dispid, DISPATCH_METHOD, VT_VARIANT,
                                   (void*)&vtResult, parms,
                                   "5+Math.sin(9)");
        }
     }
  }
}

you also need to add entry in CCustomModalDialog.h like

class CCustomModalDialog : public CDialog
{
// Construction
public:
      CString cszURL;
      HICON m_hIcon;
      CCustomModalDialog(CWnd* pParent = NULL);   // standard constructor
      void ExecuteScriptFunction();

....
....
}

just delete file custombrowserjs.cpp from workspace..now you may call and rebuild

-MAHESH
0
 
LVL 4

Author Comment

by:Cyber-Drugs
Comment Utility
That worked beautifully!

Thank you for all your time and help!! :)
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now