Приложение DLLCALL
Приложение DLLCALL работает совместно с DLL-библиотекой DLLDemo.DLL, описанной в предыдущем разделе.
Главное окно приложения DLLCALL и меню File показано на рис. 3.7.
![](image/prilozhenie-dllcall_1.gif)
Рис. 3.7. Главное окно приложения DLLCALL
Если из меню File выбрать строку Find App Window, на экране появится диалоговая панель Find Application Window, показанная на рис. 3.8.
![](image/prilozhenie-dllcall_2.gif)
Рис. 3.8. Диалоговая панель Find Application Window
Здесь в поле Enter application window title to find вы должны ввести заголовок окна приложения. Если приложение с таким заголовком запущено, оно будет найдено, после чего на экране появится соответствующее сообщение (рис. 3.9).
![](image/prilozhenie-dllcall_1.jpg)
Рис. 3.9. Сообщение о том, что заданное окно найдено
При инициализации DLL-библиотеки, вызванной подключением процесса DLLCALL, на экране возникает сообщение, показанное на рис. 3.10.
![](image/prilozhenie-dllcall_2.jpg)
Рис. 3.10. Собщение о подключении процесса к DLL-библиотеке
Когда приложение DLLCALL отключается от DLL-библиотеки, на экран выводится сообщение, показанное на рис. 3.11.
![](image/prilozhenie-dllcall_3.jpg)
Рис. 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.