Click here to Skip to main content
Licence 
First Posted 9 Jun 2002
Views 106,245
Downloads 539
Bookmarked 23 times

How to dynamically link to oleacc.dll in Visual C++ .NET

By Chen Hao | 9 Jun 2002
How to control the dependancy on oleacc.dll in your Visual C++ .NET applications
1 vote, 4.8%
1

2
1 vote, 4.8%
3

4
19 votes, 90.5%
5
4.90/5 - 27 votes
1 removed
μ 4.67, σa 1.67 [?]

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:

  • AccessibleObjectFromWindow(HWND hwnd, DWORD dwId, REFIID riid, void **ppvObject)
  • CreateStdAccessibleObject(HWND hwnd, LONG idObject, REFIID riid, void** ppvObject)
  • LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN punk)

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"));
    }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Chen Hao

Web Developer

China China

Member
Chen Hao is a programmer of SourceTec Software Co., LTD.
He began to program since 1992 and programming became
one of the most important things in his life since then.
 
His most recent projects were Sothink SWF Quicker and
Sothink SWF Decompiler.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generaldlls Pinmemberfcvjapan5:10 9 May '06  
Generalthe window close after the program run Pinsussysf021:25 5 Jul '05  
QuestionHow to get chiness String (Unicode) PinmemberLao Jing Lu23:57 20 Jun '04  
GeneralLinking error Pinmemberdiegoaso11:55 15 Mar '04  
QuestionHow do U Link a ini file in Visual C++? PinmemberDrRayen9:29 5 Mar '04  
GeneralFinding dialogs Pinmemberp_khasnis0:14 26 Dec '03  
GeneralAbout the SAFEARRAY** when using an AcgtiveX DLL Pinmemberblueeyesblue6:31 9 Nov '03  
Generaldo you have helper.... Pinmemberfiresw0:18 28 May '03  
GeneralThanks a lot Pinmemberzhangzq717:48 16 Apr '03  
Generalwhen using UNICODE Pinmemberzxmjp075:51 24 Mar '03  
Generalthanks PinsussKammerer Volker4:16 10 Jan '03  
GeneralQ325014 Addresses This Issue PinmemberJeff Briggs17:06 7 Nov '02  
GeneralRe: Q325014 Addresses This Issue PinmemberDavid Vest7:46 8 Mar '03  
GeneralProblems PinmemberDenes6:37 25 Oct '02  
AnswerRe: Problems Pinmembersajithomas1:35 23 Oct '09  
GeneralUse delayload PinmemberRama Krishna4:37 12 Jun '02  
GeneralRe: Use delayload PinmemberChen Hao16:57 13 Jun '02  
GeneralRe: Use delayload PinsussPieter Greyling9: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 | :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 PinsussJaro0:24 20 Aug '02  
GeneralRe: Use delayload PinsussAnonymous18:03 11 Oct '02  
GeneralGreat !! Thank you Pinmemberluca_covolo1:42 29 Nov '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120210.1 | Last Updated 10 Jun 2002
Article Copyright 2002 by Chen Hao
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid