Click here to Skip to main content
Email Password   helpLost your password?

Introduction

After porting one of my old VC 6.0 projects to VC 7.0, I found that all the executable files were dependant on the library oleacc.dll, which is the core file of Microsoft Active Accessibility (MSAA). Because MSAA is released in 1997, some old OSs - Windows 95, Windows NT and Windows 98 (without Active Accessibility Options installed) do not support it normally. So my program failed to run on these platforms! This has caused me quite a headache.

I checked the MFC source code and found that only these 3 procedures in oleacc.dll were called by MFC 7.0 in some member functions of class CWnd:

After did some simple researches, I found the solution:

  1. Remove the dependence to oleacc.lib from my project
    Select "Properties..." from the "Project" menu. In the configuration tree of the dialog, select catalog "Linker" and click "Input".  Click "Ignore Specific Library" and enter "oleacc.lib".
     
  2. Write my own proxy functions
    All of these functions have the same name to the corresponding MSAA APIs. In these functions, I dynamically load oldacc.dll, and then call the corresponding procedures in oleacc.dll if it is loaded successfully. I encapsulated these function to 2 files: oleaccproxy.h and oleaccproxy.cpp and then added the them to my project. The source code for the proxy is shown below.
     
  3. Rebuild the project
    After rebuilt the project, the output executable file does not depend on oleacc.dll and if MSAA is present on target platform, the MSAA features will still function properly.

Source Code

The header file

#pragma once

typedef LRESULT (_stdcall *pfnAccessibleObjectFromWindow)(HWND hwnd, DWORD dwId, 
                                                    REFIID riid, void **ppvObject);
typedef LRESULT (_stdcall *pfnCreateStdAccessibleObject)(HWND hwnd, LONG idObject, 
                                                    REFIID riid, void** ppvObject);
typedef LRESULT (_stdcall *pfnLresultFromObject)(REFIID riid, WPARAM wParam, 
                                                    LPUNKNOWN punk);

class COleaccProxy
{
public:
    COleaccProxy(void);
    virtual ~COleaccProxy(void);

private:
    static HMODULE m_hModule;
    static BOOL m_bFailed;
    
public:
    static void Init(void);
    static pfnAccessibleObjectFromWindow m_pfnAccessibleObjectFromWindow;
    static pfnCreateStdAccessibleObject m_pfnCreateStdAccessibleObject;
    static pfnLresultFromObject m_pfnLresultFromObject;
};

The implementation file

#include "StdAfx.h"

#include "oleaccproxy.h"



extern "C" LRESULT _stdcall AccessibleObjectFromWindow(HWND hwnd, DWORD dwId, 
                                                       REFIID riid, void **ppvObject)
{
    COleaccProxy::Init();
    return COleaccProxy::m_pfnAccessibleObjectFromWindow ? 
       COleaccProxy::m_pfnAccessibleObjectFromWindow(hwnd, dwId, riid, ppvObject) : 0;
}

extern "C" LRESULT _stdcall CreateStdAccessibleObject(HWND hwnd, LONG idObject, 
                                                      REFIID riid, void** ppvObject)
{
    COleaccProxy::Init();
    return COleaccProxy::m_pfnCreateStdAccessibleObject ? 
       COleaccProxy::m_pfnCreateStdAccessibleObject(hwnd, idObject, riid, ppvObject) : 0;
}

extern "C" LRESULT _stdcall LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN punk)
{
    COleaccProxy::Init();
    return COleaccProxy::m_pfnLresultFromObject ? 
       COleaccProxy::m_pfnLresultFromObject(riid, wParam, punk) : 0;
}

HMODULE COleaccProxy::m_hModule = NULL;
BOOL COleaccProxy::m_bFailed = FALSE;

pfnAccessibleObjectFromWindow COleaccProxy::m_pfnAccessibleObjectFromWindow = NULL;
pfnCreateStdAccessibleObject COleaccProxy::m_pfnCreateStdAccessibleObject = NULL;
pfnLresultFromObject COleaccProxy::m_pfnLresultFromObject = NULL;

COleaccProxy::COleaccProxy(void)
{
}

COleaccProxy::~COleaccProxy(void)
{
}

void COleaccProxy::Init(void)
{
    if (!m_hModule && !m_bFailed)
    {
        m_hModule = ::LoadLibrary(_T("oleacc.dll"));
        if (!m_hModule)
        {
            m_bFailed = TRUE;
            return;
        }

        m_pfnAccessibleObjectFromWindow
             = (pfnAccessibleObjectFromWindow)::GetProcAddress(m_hModule, 
                                                          _T("AccessibleObjectFromWindow"));
        m_pfnCreateStdAccessibleObject
             = (pfnCreateStdAccessibleObject)::GetProcAddress(m_hModule, 
                                                          _T("CreateStdAccessibleObject"));
        m_pfnLresultFromObject = (pfnLresultFromObject)::GetProcAddress(m_hModule, 
                                                          _T("LresultFromObject"));
    }
}
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
Generaldlls
fcvjapan
5:10 9 May '06  
Well i need to know how to use an existing dll, ex:
In Borland c++ to run my application i need to use the bolndmm.dll
and files.bpl(package library), i can send my app only with de executable ?
without this files ?

#DEFINE _C_PROGRAMMER_
Generalthe window close after the program run
ysf02
1:25 5 Jul '05  
Hi ,

my problem is when write the code on c++ and start to run it the program run correctly but the window (console) close quickly

ex) if my program contain cout << "hellow" ;

in the last sentnce
the the window show it but it close it quickly

i wonder where is the problem ( from IDE or WIN XP)

by the way i use vc++.net to run my code

GeneralHow to get chiness String (Unicode)
Lao Jing Lu
23:57 20 Jun '04  
Hi !
I use VC++7.1 run on Windows XP OS (Version English).
In Dialog, I use Rich Edit 2.0 can display chiness String, but I can not get the Chiness String in Rich Edit 2.0 (OR EditBox) by GetWindowText() Funtion.

How to do it?

JinLu
GeneralLinking error
diegoaso
11:55 15 Mar '04  
Hi, Im migrating a code from VC++ 6.0 to VC 7.0 (.NET). and im getting a lot of linking errors that look like this:

error LNK2001: unresolved external symbol "__declspec(dllimport) int __cdecl SymixDBBeginTrans(class ATL::CStringT > >)" (__imp_?SymixDBBeginTrans@@YAHV?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z)

or these

error LNK2019: unresolved external symbol "__declspec(dllimport) int __cdecl SymixDBBeginTrans(class ATL::CStringT > >)" (__imp_?SymixDBBeginTrans@@YAHV?$CStringT@DV?$StrTraitMFC@DV?$ChTraitsCRT@D@ATL@@@@@ATL@@@Z) referenced in function "public: int __thiscall CFSFilter::SaveToDisk(int)" (?SaveToDisk@CFSFilter@@QAEHH@Z)



Can someone help me please, im in a rush for this, so i will really apreciate it

Thanks

Diego

Diego
GeneralHow do U Link a ini file in Visual C++?
DrRayen
9:29 5 Mar '04  
Hi I wanna know if someone can tell me how u can link a ini file using VC++ to acces a remote database...
Suspicious
GeneralFinding dialogs
p_khasnis
0:14 26 Dec '03  
Hello,

I am trying to use MSAA to capture dialog boxes(like alert, confirmation, prompt, Basic user authentication, etc) displayed by IE. I have been able to capture these dialogs and get the user actions on them. I am also able to replay events on these dialogs.

I am using get_accName() api to get the name of hwnd of the control and using name to find the dialog that i want.
For e.g
if((strcmp(buffer,"Enter Network Password")==0)
{
//Found Authentication dialog
}

When i tested this on XP i found that the name (for Basic authentication dialog) changed to "Connect to xxx" xxx being the domain name for the requested page. Now i have modified the comparision to include "Connect" so that i can find the dialog.

1) If the local changes does the name of the dialog changes or does it remain the same.

2)If there is anyway to find a particular dialog. I checked the class for alert, prompt etc and all of them are of type Dialog class.

PS. I tried to get the child count for these dialogs by using the api get_accChildCount() and all of them have count of 7. I really dont know why. My guess is that the controls are hidden for some dialogs, i maybe wrong here.

Any help is appreciated.

Thanks in advance.
Prasad.
GeneralAbout the SAFEARRAY** when using an AcgtiveX DLL
blueeyesblue
6:31 9 Nov '03  
Confused Hi, I need your help!!



I have the problems about the SAFEARRAY** when trying to use an ActiveX DLL in VC.NET. It’s an array as Integer. And I tried to use the dll in VC6 but I failed. It didn’t recognize the var type.



The code of the DLL in VB6 is like this:



Public Function fun(A() As Integer) As Boolean

fun = True

End Function



The definition of the function in VC class head file is like this:

BOOL fun(SAFEARRAY * * A)

{

BOOL result;

static BYTE parms[] = VTS_UNKNOWN ;

InvokeHelper(0x60030000, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, A);

return result;

}

I know the VTS_UNKNOWN is exactly wrong, but I have no idea what it should be. I shall ask you for help. Can you tell me your approaches please? Thank you!

blueeyesblue
Generaldo you have helper....
firesw
0:18 28 May '03  
Implement a program which can perform the following actions:

Prompt the user for input file name, read the file and determine the number of alphanumeric characters, the number of words, the number of sentences in the file. To determine the number of sentences the number of periods (dots) should be counted (newlines and tabs should be disregarded). Allow the user to press any keys to return back to the main menu.

Prompt the user for the input and output file names, append the contents of one file to another. Allow the user to press any keys to return back to the main menu.

Prompt the user for input file name, word the user want to replace, and the substitute word. Open the file and replace all the occurrence of the user specified word by another word in the entire file. After all, tell the user how many replaces have been taken place. Allow the user to press any keys to return back to the main menu.

Exit the program.


the c plus plus program. how to write.

Implement a program which can perform the following actions:

Prompt the user for input file name, read the file and determine the number of alphanumeric characters, the number of words, the number of sentences in the file. To determine the number of sentences the number of periods (dots) should be counted (newlines and tabs should be disregarded). Allow the user to press any keys to return back to the main menu.

Prompt the user for the input and output file names, append the contents of on
GeneralThanks a lot
zhangzq71
7:48 16 Apr '03  
I am finding a solution for this problem, your is very very good.

Rose

email:zhangzq71@hotmail.com
Generalwhen using UNICODE
zxmjp07
5:51 24 Mar '03  
From my point of view, the function GetProcAddress takes as the second argument an ANSI string, so the macro _T gives an error message in my environment with _UNICODE defined.

Great work, just what I was seaching for!
Generalthanks
Kammerer Volker
4:16 10 Jan '03  
really great article..... !!!!
GeneralQ325014 Addresses This Issue
Jeff Briggs
17:06 7 Nov '02  
Great Article.

Also, in case anyone is interested, you can now obtain a QFE (HotFix) for this by contacting Microsoft Support Services and requesting it. The KB article id is Q325014.

It works when using MFC in a shared library.


GeneralRe: Q325014 Addresses This Issue
David Vest
7:46 8 Mar '03  
Just a word of warning, the QFE has restrictions on what you can redistribute, e.g. you are NOT allowed to just redistribute the MFC70, instead you have to redistribute a msi package.

This may not be a problem for developers developing internal company applications but is a huge headache for developers writing applications for general public use.

Dave.
GeneralProblems
Denes
6:37 25 Oct '02  
I don't know if I am doing anything wrong, but for some reason using delay load with the MFC libs shared still requires this dll. I get this warning when linking this way:
"LINK : warning LNK4199: /DELAYLOAD:oleacc.dll ignored; no imports found from oleacc.dll"
It works fine when I use MFC statically though. Any ideas?

When I use MFC libs statically in Release I don't seem to get all proper error messages so I am trying to avoid doing that. For example, if a file on my recent file list has been deleted and I try to open it using the recent file list, the message box saying the file contains an invalid path appears blank. Same thing seems to happen with print preview and no printer setup. This doesn't happen in debug or when MFC libs are shared. Anybody know why?

AnswerRe: Problems
sajithomas
1:35 23 Oct '09  
Hi Try this!.. Select projet's properties | Linker | Input, click on the button on the Delay load DLL click on the [...] button to open the dialog for Delay Loaded DLLs property, and that's where you see the "Inherit from parent or project defaults" checkbox. After unchecking, you'll see that the property is $(NOINHERIT) and that fixes the problem. Big Grin Sebastin
GeneralUse delayload
Rama Krishna
4:37 12 Jun '02  
The delay load feature of VC is supposed to help you with this. Build the application and to teh linker settings add /delayload:oleacc.dll This will load the dll only when the function is called. So you will not have any problems. You can even write custom error handling.

..this is a VB Programmers' world and we all are just visitors - Someone in a MSJ article
GeneralRe: Use delayload
Chen Hao
16:57 13 Jun '02  
Yes, this's a better and simpler solution. I've test and it works fine. Thanks a lot!
GeneralRe: Use delayload
Pieter Greyling
9:46 15 Aug '02  
Great thanks both Chen and Rama.
I discovered this problem during deployment of an enterprise GUI application built in Borland C++Builder that rides on top of an inproc COM dll I wrote using VC++/ATL/MFC v.6.0 -> v.7.0. It was a somewhat clasically uncomfortable surprise to be in this situation after successfully testing the app "everywhere"Confused ! I used Chen's solution for my project first and I am very glad I did - for the sake of understanding and control-freakiness Wink
GeneralRe: Use delayload
Jaro
0:24 20 Aug '02  
It works fine for Use MFC in a Shared DLL.
When I'm using MFC in a Static Library I get

oleacc.lib(OLEACC.dll) : error LNK2001: unresolved external symbol ___delayLoadHelper2@8


GeneralRe: Use delayload
Anonymous
18:03 11 Oct '02  
You should add "delayimp.lib" to your project.
GeneralGreat !! Thank you
luca_covolo
1:42 29 Nov '02  
Great !! Thank you


Last Updated 10 Jun 2002 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010