Программирование для Windows NT (том 2)

Приложение DLLCALL


Приложение DLLCALL работает совместно с DLL-библиотекой DLLDemo.DLL, описанной в предыдущем разделе.

Главное окно приложения DLLCALL и меню File показано на рис. 3.7.

Рис. 3.7. Главное окно приложения DLLCALL

Если из меню File выбрать строку Find App Window, на экране появится диалоговая панель Find Application Window, показанная на рис. 3.8.

Рис. 3.8. Диалоговая панель Find Application Window

Здесь в поле Enter application window title to find вы должны ввести заголовок окна приложения. Если приложение с таким заголовком запущено, оно будет найдено, после чего на экране появится соответствующее сообщение (рис. 3.9).

Рис. 3.9. Сообщение о том, что заданное окно найдено

При инициализации DLL-библиотеки, вызванной подключением процесса DLLCALL, на экране возникает сообщение, показанное на рис. 3.10.

Рис. 3.10. Собщение о подключении процесса к DLL-библиотеке



Когда приложение DLLCALL отключается от DLL-библиотеки, на экран выводится сообщение, показанное на рис. 3.11.

Рис. 3.11. Сообщение об отключении процесса от DLL-библиотеки

Главный файл исходных текстов приложения DLLCALL представлен в листинге 3.4.

Листинг 3.4. Файл dlldemo\dllcall\dllcall.c

// ==================================================

// Приложение DLLCall

// Вызов функции из DLL-библиотеки

//

// (С) Фролов А.В., 1996

// Email: frolov@glas.apc.org

// ==================================================

#define STRICT

#include <windows.h>

#include <windowsx.h>

#include "resource.h"

#include "afxres.h"

#include "dllcall.h"

// Определяем тип: указатель на функцию

typedef HWND (WINAPI *MYDLLPROC)(LPSTR);

// Указатель на функцию, расположенную в

// DLL-библиотеке

MYDLLPROC GetAppWindow;

// Буфер для заголовка окна, поиск которого

// будет выполняться

char szWindowTitle[512];

// Идентификатор DLL-библиотеки

HANDLE hDLL;

HINSTANCE hInst;

char szAppName[]  = "DLLCallApp";


char szAppTitle[] = "DLL Call Demo";

// -----------------------------------------------------

// Функция WinMain

// -----------------------------------------------------

int APIENTRY

WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

        LPSTR lpCmdLine, int nCmdShow)

{

  WNDCLASSEX wc;

  HWND hWnd;

  MSG msg;

 

  // Сохраняем идентификатор приложения

  hInst = hInstance;

  // Преверяем, не было ли это приложение запущено ранее

  hWnd = FindWindow(szAppName, NULL);

  if(hWnd)

  {

    // Если было, выдвигаем окно приложения на

    // передний план

    if(IsIconic(hWnd))

           ShowWindow(hWnd, SW_RESTORE);

         SetForegroundWindow(hWnd);

    return FALSE;

  }

  // Регистрируем класс окна

  memset(&wc, 0, sizeof(wc));

  wc.cbSize = sizeof(WNDCLASSEX);

  wc.hIconSm = LoadImage(hInst,

    MAKEINTRESOURCE(IDI_APPICONSM),

    IMAGE_ICON, 16, 16, 0);

  wc.style = 0;

  wc.lpfnWndProc = (WNDPROC)WndProc;

  wc.cbClsExtra  = 0;

  wc.cbWndExtra  = 0;

  wc.hInstance = hInst;

  wc.hIcon = LoadImage(hInst,

    MAKEINTRESOURCE(IDI_APPICON),

    IMAGE_ICON, 32, 32, 0);

  wc.hCursor = LoadCursor(NULL, IDC_ARROW);

  wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);

  wc.lpszMenuName = MAKEINTRESOURCE(IDR_APPMENU);

  wc.lpszClassName = szAppName;

  if(!RegisterClassEx(&wc))

    if(!RegisterClass((LPWNDCLASS)&wc.style))

         return FALSE;

   

  // Создаем главное окно приложения

  hWnd = CreateWindow(szAppName, szAppTitle,

     WS_OVERLAPPEDWINDOW,

     CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,

     NULL, NULL, hInst, NULL);

  if(!hWnd) return(FALSE);

  // Отображаем окно и запускаем цикл

  // обработки сообщений

  ShowWindow(hWnd, nCmdShow);

  UpdateWindow(hWnd);

  while(GetMessage(&msg, NULL, 0, 0))

  {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

  }

  return msg.wParam;

}

// -----------------------------------------------------



// Функция WndProc

// -----------------------------------------------------

LRESULT WINAPI

WndProc( HWND hWnd, UINT msg, WPARAM wParam,

        LPARAM lParam)

{

  switch(msg)

  {

    HANDLE_MSG(hWnd, WM_COMMAND, WndProc_OnCommand);

    HANDLE_MSG(hWnd, WM_DESTROY, WndProc_OnDestroy);

    default:

      return(DefWindowProc(hWnd, msg, wParam, lParam));

  }

}

// -----------------------------------------------------

// Функция WndProc_OnDestroy

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnDestroy(HWND hWnd)

{

  PostQuitMessage(0);

  return 0L;

}

// -----------------------------------------------------

// Функция WndProc_OnCommand

// -----------------------------------------------------

#pragma warning(disable: 4098)

void WndProc_OnCommand(HWND hWnd, int id,

  HWND hwndCtl, UINT codeNotify)

{

  switch (id)

  {

    case ID_FILE_EXIT: 

    {

      // Завершаем работу приложения

      PostQuitMessage(0);

      return 0L;

      break;

    }

        

    case ID_FILE_FINDWINDOW:

    {

      // Отображаем диалоговую панель для ввода

      // заголовка главного окна приложения,

      // поиск которого будет выполняться

      if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DLGFIND),

        hWnd, DlgProc))

      {

        // Первый способ вызова функции из DLL-библиотеки:

        // прямой вызов с использованием библиотеки экспорта

/*

        // Выполняем поиск окна с заголовком, заданным

        // при помощи диалоговой панели

        if(FindApplicationWindow(szWindowTitle) != NULL)

          MessageBox(NULL, "Application window was found",

            szAppTitle, MB_OK | MB_ICONINFORMATION);

       

          else

          MessageBox(NULL, "Application window was not found",

            szAppTitle, MB_OK | MB_ICONINFORMATION);

*/

        // Второй способ вызова функции из DLL-библиотеки:

        // загрузка DLL-библиотеки функцией LoadLibrary



        // Загружаем DLL-библиотеку

        hDLL = LoadLibrary("DLLDEMO.DLL");

        // Если библиотека загружена успешно, выполняем

        // вызов функции

        if(hDLL != NULL)

        {

          // Получаем адрес нужной нам функции

          GetAppWindow =

            (MYDLLPROC)GetProcAddress(hDLL,

              "FindApplicationWindow");

          // Если адрес получен, вызываем функцию

          if(GetAppWindow != NULL)

          {

            // Выполняем поиск окна с заголовком, заданным

            // при помощи диалоговой панели

            if(GetAppWindow(szWindowTitle) != NULL)

              MessageBox(NULL, "Application window was found",

                szAppTitle, MB_OK | MB_ICONINFORMATION);

            else

              MessageBox(NULL,

                "Application window was not found",

                szAppTitle, MB_OK | MB_ICONINFORMATION);

          }

         

          // Освобождаем DLL-библиотеку

          FreeLibrary(hDLL);

        }

      }

 

      break;     

    }

   

    case ID_HELP_ABOUT:

    {

      MessageBox(hWnd,

        "DLL Call Demo\n"

        "(C) Alexandr Frolov, 1996\n"

        "Email: frolov@glas.apc.org",

        szAppTitle, MB_OK | MB_ICONINFORMATION);

            return 0L;

            break;

    }

       default:

           break;

  }

  return FORWARD_WM_COMMAND(hWnd, id, hwndCtl, codeNotify,

    DefWindowProc);

}

// -----------------------------------------------------

// Функция DlgProc

// -----------------------------------------------------

LRESULT WINAPI

DlgProc( HWND hdlg, UINT msg, WPARAM wParam,

        LPARAM lParam)

{

  switch(msg)

  {

    HANDLE_MSG(hdlg, WM_INITDIALOG, DlgProc_OnInitDialog);

    HANDLE_MSG(hdlg, WM_COMMAND,    DlgProc_OnCommand);

       default:

    return FALSE;

  }

}

// -----------------------------------------------------



// Функция DlgProc_OnInitDialog

// -----------------------------------------------------

BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus,

                          LPARAM lParam)

{

  return TRUE;

}

// -----------------------------------------------------

// Функция DlgProc_OnCommand

// -----------------------------------------------------

#pragma warning(disable: 4098)

void DlgProc_OnCommand(HWND hdlg, int id,

  HWND hwndCtl, UINT codeNotify)

{

  switch (id)

  {

    case IDOK:

    {

      // Если пользователь нажал кнопку OK,

      // получаем текст из поля редактирования и

      // сохраняем его в глобальном буфере szWindowTitle

      GetDlgItemText(hdlg, IDC_EDIT1, szWindowTitle, 512); 

     

      // Завершаем работу диалоговой панели

      EndDialog(hdlg, 1);

      return TRUE;

    }

    // Если пользователь нажимает кнопку Cancel,

    // завершаем работу диалоговой панели

    case IDCANCEL:

    {

      // Завершаем работу диалоговой панели

      EndDialog(hdlg, 0);

      return TRUE;

    }

    default:

      break;

  }

  return FALSE;

}

Файл dllcall.h (листинг 3.5) содержит прототипы функций, определенных в приложении DLLCALL.

Листинг 3.5. Файл dlldemo\dllcall\dllcall.h

// -----------------------------------------------------

// Описание функций

// -----------------------------------------------------

LRESULT WINAPI

WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

void WndProc_OnCommand(HWND hWnd, int id,

  HWND hwndCtl, UINT codeNotify);

void WndProc_OnDestroy(HWND hWnd);

HWND FindApplicationWindow(LPSTR lpszWindowTitle);

LRESULT WINAPI

DlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam);

BOOL DlgProc_OnInitDialog(HWND hdlg, HWND hwndFocus,

                          LPARAM lParam);

void DlgProc_OnCommand(HWND hdlg, int id,

  HWND hwndCtl, UINT codeNotify);

В файле dllcall.rc (листинг 3.6) определены ресурсы приложения DLLCALL. Это меню, две пиктограммы и диалоговая панель, а также текстовые строки, которые не используются.



Листинг 3.6. Файл dlldemo\dllcall\dllcall.rc

// Microsoft Developer Studio generated resource script.

//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "afxres.h"

//////////////////////////////////////////////////////////////

#undef APSTUDIO_READONLY_SYMBOLS

//////////////////////////////////////////////////////////////

// Russian resources

#if !defined(AFX_RESOURCE_DLL) defined(AFX_TARG_RUS)

#ifdef _WIN32

LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT

#pragma code_page(1251)

#endif //_WIN32

//////////////////////////////////////////////////////////////

//

// Menu

//

IDR_APPMENU MENU DISCARDABLE

BEGIN

    POPUP "&File"

    BEGIN

        MENUITEM "F&ind App Window",   ID_FILE_FINDWINDOW

        MENUITEM SEPARATOR

        MENUITEM "E&xit",              ID_FILE_EXIT

    END

    POPUP "&Help"

    BEGIN

        MENUITEM "&About...",          ID_HELP_ABOUT

    END

END

#ifdef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// TEXTINCLUDE

//

1 TEXTINCLUDE DISCARDABLE

BEGIN

    "resource.h\0"

END

2 TEXTINCLUDE DISCARDABLE

BEGIN

    "#include ""afxres.h""\r\n"

    "\0"

END

3 TEXTINCLUDE DISCARDABLE

BEGIN

    "\r\n"

    "\0"

END

#endif    // APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Icon

//

// Icon with lowest ID value placed first to ensure

// application icon

// remains consistent on all systems.

IDI_APPICON             ICON    DISCARDABLE     "Dllcall.ico"

IDI_APPICONSM           ICON    DISCARDABLE     "Dllcalsm.ico"

//////////////////////////////////////////////////////////////



//

// Dialog

//

IDD_DLGFIND DIALOG DISCARDABLE  0, 0, 247, 74

STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

CAPTION "Find Application Window"

FONT 8, "MS Sans Serif"

BEGIN

    EDITTEXT        IDC_EDIT1,21,31,152,16,ES_AUTOHSCROLL

    DEFPUSHBUTTON   "OK",IDOK,190,7,50,14

    PUSHBUTTON      "Cancel",IDCANCEL,190,24,50,14

    GROUPBOX        "Enter application window title to find",

                    IDC_STATIC,13,13,167,49

END

//////////////////////////////////////////////////////////////

//

// DESIGNINFO

//

#ifdef APSTUDIO_INVOKED

GUIDELINES DESIGNINFO DISCARDABLE

BEGIN

    IDD_DLGFIND, DIALOG

    BEGIN

        LEFTMARGIN, 7

        RIGHTMARGIN, 240

        TOPMARGIN, 7

        BOTTOMMARGIN, 67

    END

END

#endif    // APSTUDIO_INVOKED

#endif    // Russian resources

//////////////////////////////////////////////////////////////

#ifndef APSTUDIO_INVOKED

//////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 3 resource.

//

//////////////////////////////////////////////////////////////

#endif    // not APSTUDIO_INVOKED

Файл resource.h (листинг 3.7) содержит определения констант для файла описания ресурсов приложения.

Листинг 3.7. Файл dlldemo\dllcall\resource.h

//{{NO_DEPENDENCIES}}

// Microsoft Developer Studio generated include file.

// Used by DLLCall.rc

//

#define IDR_MENU1                       101

#define IDR_APPMENU                     101

#define IDI_APPICON                     102

#define IDI_APPICONSM                   103

#define IDD_DLGFIND                     104

#define IDC_EDIT1                       1000

#define ID_FILE_EXIT                    40001

#define ID_HELP_ABOUT                   40002

#define ID_FILE_FINDWINDOW              40003

// Next default values for new objects

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        105

#define _APS_NEXT_COMMAND_VALUE         40004

#define _APS_NEXT_CONTROL_VALUE         1001

#define _APS_NEXT_SYMED_VALUE           101

#endif

#endif

Рассмотрим исходные тексты приложения DLLCALL.


Содержание раздела