Windows приложение для просмотра графических файлов
Министерство образования и науки Российской Федерации
ФГАОУ ВПО «УРАЛЬСКИЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ
имени первого Президента России Б.Н.Ельцина»
Оценка работы
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовой работе
«Windows приложение для просмотра графических файлов»
Подпись Дата Ф.И.О.
Руководитель Зеленская Е.В.
Студент Семенкин Л.В.
Группа Р-38032
Екатеринбург 2010
Содержание.
Введение 4
Введение
В настоящее время, обозреватель графических файлов является одной из тех программ, без которых обычный пользователь не представляет свой компьютер. Большинство людей хранит на своем компьютере фотографии, картинки и для их просмотра необходима такая программа.
Современные графические обозреватели поддерживают большое количество форматов, и имеют возможность редактирования графики, в нашем обозревателе эта функция отсутствует.
1.Теоретическая часть
1.1 Обозреватель графических файлов
Обозреватель графических файлов компьютерная программа, предназначенная для просмотра графических файлов .В нашем случае поддерживает форматы: BMP, JPEG, JPG, TIFF, GIF, PNG.
.
1.2 Библиотека классов GDI+
GDI (Graphics Device Interface, Graphical Device Interface) один из трёх основных якомпонентов или «подсистем», вместе с ядром и Windows API составляющих пользовательский интерфейс (оконный менеджер GDI) Microsoft Windows.
GDI это интерфейс Windows для представления графических объектов и передачи их на устройства отображения, такие как мониторы и принтеры.
GDI отвечает за отрисовку линий и кривых, отображение шрифтов и обработку палитры. Он не отвечает за отрисовку окон, меню и т. п., эта задача закреплена за пользовательской подсистемой, располагающейся в user32.dll и основывающейся на GDI. GDI выполняет те же функции, что и QuickDraw в Mac OS.
Одно из преимуществ использования GDI вместо прямого доступа к оборудованию это унификация работы с различными устройствами. Используя GDI, можно одними и теми же функциями рисовать на разных устройствах, таких, как экран или принтер, получая на них практически одинаковые изображения. Эта возможность лежит в центре всех WYSIWYG-приложений для Windows.
Простые игры, которые не требуют быстрой графики, могут использовать GDI. Однако GDI не обеспечивает качественной анимации, поскольку в нём нет возможности синхронизации с кадровым буфером. Также, в GDI нет растеризации для отрисовки 3D-графики. Современные игры используют DirectX или OpenGL, что даёт программистам доступ к большему количеству аппаратных возможностей.
С выходом Windows XP появился потомок подсистемы, GDI+, основанной на C++.
GDI+ является улучшенной средой для 2D-графики, в которую добавлены такие возможности, как сглаживание линий (antialiasing), использование координат с плавающей точкой, градиентная заливка, внутренняя поддержка таких графических форматов, как JPEG и PNG, преобразования двумерных матриц и т. п. GDI+ использует ARGB-цвета. Эти возможности используются в пользовательском интерфейсе Windows XP, а их присутствие в базовом графическом слое облегчает использование систем векторной графики, таких, как Flash или SVG.
Динамические библиотеки GDI+ могут распространяться вместе с приложениями для использования в предыдущих версиях Windows.
2. Инструкция программиста
Для работы с графическими файлами была подключена библиотека gdiplus.dll
- Сообщения:
- WM_CREATE- отправляется тогда, когда программа запрашивает, какое окно будет создаваться вызовом функции или CreateWindow. (Сообщение посылается перед возвращением значения функцией). Оконная процедура нового окна принимает это сообщение после того, как окно создано, но до того, как окно становится видимым.
- WM_COMMAND- отправляется тогда, когда пользователь выбирает командный элемент из меню, когда орган управления отправляет уведомительное сообщение в свое родительское окно, или когда транслируется нажатие клавиши - ускорителя.
- IDM_EXIT- выход из программы
- OPENFILE- открытие файла
- CHOOSEDIR- выбор директории
- FORWARD- далее
- BACKWARD- назад
- FILESLIST- список файлов
- WM_PAINT- это сообщение указывает оконной процедуре, что часть рабочей области окна (или все окно) требует перерисовки.
- WM_SIZING- сообщение указывающее расположение интерфейса при изменении размера окна.
WM_SYSCOMMAND Окно получает это сообщение тогда, когда пользователь выбирает команду из Системного меню окна (прежде известное как системное или управляющее меню) или когда пользователь выбрал кнопку развертывания, свертывания, восстановления или закрытия окна. Кнопка развертывания в данном случае заблокирована.
- WM_DESTROY- посылается тогда, когда пользователь закрывает окно любым способом (кнопкой закрытия окна, с помощью пункта системного меню "Закрыть", с помощью нажатия [ALT]+[F4]).
При получении этого сообщения оконная процедура обычно освобождает память и "подготавливается" к уничтожению окна. В нашем случае, поскольку программа создает единственное окно, при его закрытии должна завершаться вся программа.
Обработчики событий:
void AddFilter добавляет фильтр форматов файла
void DeleteFilter удаляет фильтр
void AddFile добавление файла
void DeleteFileFromList- удаляет файл из списка
void DelteFileFromListByIndex удаляет файл из списка по полному имени
void AddGroupOfFiles- добавляет группу файлов
void ClearFileList- очищает список файлов
void ClearFilterList очищает лист фильтров
inline long GetFilesListSize получение размера файла
TCHAR* GetShortNameByIndex строковый указатель на длину списка файлов
bool FiltrateFile- производит фильтрацию файлов по формату
3. Инструкция пользователя.
После запуска программы, для того чтобы включилось управление, необходимо открыть графический файл, либо директорию, это осуществляется при нажатии соответствующих кнопок
Кнопки перемотки “<<” и “>>”
Для выхода из программы Файл-> Выход
4. Тестирование
Запуск приложения (рис.1).
Рис 1.
Открытие директории (рис.2)
Рис 2
Заключение
В данной курсовой работе была реализована программа для просмотра графических файлов. Программа оснащена набором функций: открывания как одного файла , так и директории, перелистывание файлов при помощи кнопок “далее” и “обратно”, так же пишется информация о файле: имя файла, тип и размер в байтах.
В ходе выполнения работы, мной были закреплены навыки работы с объектно-ориентированным программированием в среде .NET, в том числе я познакомился с этапами разработки программного обеспечения. Получены навыки создания приложений для ОС Windows, среди них работа с графическим интерфейсом, подключение библиотек DGIPlus.
Реализованная мною программа была разработана в рамках учебного процесса, в связи с этим не имеет высокой конкурентно способности, тем не менее, в дальнейшем возможна оптимизация работы программы, увеличения числа функций, возможность редактирования графического файла
Библиографический список
- Щупак Ю.А. “Win32 API. Эффективная разработка приложений” Учебник СПб.: ПИТЕР, 2007
- “Компьютерная документация от А до Я”
http://www.compdoc.ru/prog/cpp/cpplesson95/index6.shtmlПриложение
Исходный текст программы.
Файл FilesListMaker.cpp
#include "stdafx.h"
#include "FilesListMaker.h"
#include <shlwapi.h> //add lib ShLwApi.lib
void FilesListMaker::AddFilter(TCHAR *tFilter)
{
FileExtFilter FilterToAdd;
lstrcpyn(FilterToAdd.FileExt,tFilter,FILTER_MAX_LEN);
CharLowerBuff((LPWSTR)FilterToAdd.FileExt,FILTER_MAX_LEN);
AllowedExtensions.push_back(FilterToAdd);
}
void FilesListMaker::DeleteFilter(TCHAR *tFilter)
{
FileExtFilter FilterToDel;
lstrcpyn(FilterToDel.FileExt,tFilter,FILTER_MAX_LEN);
CharLowerBuff((LPWSTR)FilterToDel.FileExt,FILTER_MAX_LEN);
vector<FileExtFilter>::iterator it=AllowedExtensions.begin();
for(it;it!=AllowedExtensions.end();it++)
{
if(!lstrcmp((*it).FileExt,FilterToDel.FileExt))
{
AllowedExtensions.erase(it);
break;
}
}
}
void FilesListMaker::AddFile(TCHAR *tFullFileName)
{
FileNames fnFileToAdd;
lstrcpyn(fnFileToAdd.FileName,PathFindFileName(tFullFileName),MAX_FILENAME_LEN);
lstrcpyn(fnFileToAdd.FullFilePath,tFullFileName,MAX_FULL_PATH_LEN);
Files.push_back(fnFileToAdd);
}
void FilesListMaker::AddGroupOfFiles(TCHAR *tFileDir)
{
FileNames fnFileToAdd;
TCHAR dir[MAX_FULL_PATH_LEN+2];
WIN32_FIND_DATA w32SearchingFile;
ZeroMemory(&w32SearchingFile,sizeof(WIN32_FIND_DATA));
lstrcpyn(dir,tFileDir,MAX_FULL_PATH_LEN-1);
lstrcat(dir,_TEXT("\\*"));
HANDLE hFile=FindFirstFile(dir,&w32SearchingFile);
if(hFile!=INVALID_HANDLE_VALUE)
{
lstrcpyn(fnFileToAdd.FileName,w32SearchingFile.cFileName,
min(MAX_FILENAME_LEN,MAX_PATH));
lstrcpyn(fnFileToAdd.FullFilePath,tFileDir,MAX_FULL_PATH_LEN-MAX_FILENAME_LEN-1);
lstrcat(fnFileToAdd.FullFilePath,_TEXT("\\"));
lstrcat(fnFileToAdd.FullFilePath,fnFileToAdd.FileName);
if(FiltrateFile(fnFileToAdd.FullFilePath))
{
Files.push_back(fnFileToAdd);
}
}
while (FindNextFile(hFile,&w32SearchingFile))
{
lstrcpyn(fnFileToAdd.FileName,w32SearchingFile.cFileName,
min(MAX_FILENAME_LEN,MAX_PATH));
lstrcpyn(fnFileToAdd.FullFilePath,tFileDir,MAX_FULL_PATH_LEN-MAX_FILENAME_LEN-1);
lstrcat(fnFileToAdd.FullFilePath,_TEXT("\\"));
lstrcat(fnFileToAdd.FullFilePath,fnFileToAdd.FileName);
if(FiltrateFile(fnFileToAdd.FullFilePath))
{
Files.push_back(fnFileToAdd);
}
}
FindClose(hFile);
/*vector<FileNames>::iterator it=Files.begin();
for(it;it!=Files.end();it++)
{
MessageBox(0,(*it).FullFilePath,
(*it).FileName,MB_OK);
}*/
}
void FilesListMaker::DeleteFileFromList(TCHAR* tFullPathToFile)
{
vector<FileNames>::iterator it=Files.begin();
for(it;it!=Files.end();it++)
{
if(!lstrcmp((*it).FullFilePath,tFullPathToFile))
{
Files.erase(it);
break;
}
}
}
void FilesListMaker::DelteFileFromListByIndex(long lIndex)
{
Files.erase(Files.begin()+lIndex);
}
void FilesListMaker::ClearFileList()
{
Files.erase(Files.begin(),Files.end());
}
void FilesListMaker::ClearFilterList()
{
AllowedExtensions.erase(AllowedExtensions.begin(),
AllowedExtensions.end());
}
bool FilesListMaker::FiltrateFile(TCHAR *tFullPathToFile)
{
TCHAR FileExt[FILTER_MAX_LEN];
lstrcpyn(FileExt,PathFindExtension(tFullPathToFile),FILTER_MAX_LEN);
CharLowerBuff((LPWSTR)FileExt,FILTER_MAX_LEN);
vector<FileExtFilter>::iterator it=AllowedExtensions.begin();
for(it;it!=AllowedExtensions.end();it++)
{
if(!lstrcmp((*it).FileExt,FileExt))
{
return true;
break;
}
}
return false;
}
TCHAR* FilesListMaker::operator [](unsigned long lIndex)
{
if(lIndex<Files.size()&&(Files.size()>0))
{
return Files[lIndex].FullFilePath;
}
else
{
if(Files.size())
return Files[0].FullFilePath;
else return NULL;
}
}
TCHAR* FilesListMaker::GetShortNameByIndex(unsigned long lIndex)
{
if(lIndex<Files.size()&&(Files.size()>0))
return Files[lIndex].FileName;
else
{
if(Files.size())
return Files[0].FileName;
else return NULL;
}
}
Файл PictureViewer_with_GdiPlus.cpp
#include "stdafx.h"
#include "PictureViewer_with_GdiPlus.h"
#include "GDIPlusLoader.h"
#include "FilesListMaker.h"
#include <commdlg.h>
#include <shlobj.h>
#include <shlwapi.h>
using namespace AdvDrawing;
#define MAX_LOADSTRING 100
#define XStart 50
#define YStart 20
#define MinWidth 950
#define MinHeight 660
#define MaxWidth 1000
#define MaxHeight 700
#define OPENFILE 11
#define CHOOSEDIR 22
#define FORWARD 33
#define BACKWARD 44
#define FILESLIST 55
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void Paint(HDC hdc, const RECT* rect, TCHAR* tFileName, HWND hWnd);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
GDIPlusLoader GdiPlus;
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_PICTUREVIEWER_WITH_GDIPLUS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_PICTUREVIEWER_WITH_GDIPLUS));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if(msg.message==WM_DESTROY)
{
GdiPlus.~GDIPlusLoader();
}
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PICTUREVIEWER_WITH_GDIPLUS));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_PICTUREVIEWER_WITH_GDIPLUS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW,
XStart, YStart, MinWidth, MinHeight,
NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#define RELATIVE_X_OPForDBUTTON_COORD 4.2
#define RELATIVE_Y_OPForDBUTTON_COORD 14
#define BUTTON_WIDTH 38
#define BUTTON_HEIGHT 38
#define BUTTON_SPACING 40
int wmId, wmEvent;
PAINTSTRUCT ps;
static RECT clRect;
static RECT* rWinSize;
static int CurWidth,CurHeight;
static long lListIndex=0;
static FilesListMaker GraphFiles;
HDC hdc;
static HWND hOpenFBut,hChooseDirBut,
hForwBut,hBackwBut,hFilesListLb;
static HBITMAP hOpFIc,hChDIc, hForwBIc, hBackwBIc;
static OPENFILENAME ofnOpenGr;
static BROWSEINFO biPath;
static ITEMIDLIST* iList;
static TCHAR FullPath[MAX_FULL_PATH_LEN], FileName[MAX_FILENAME_LEN];
DWORD dwErr;
TCHAR txt[10];
switch (message)
{
case WM_CREATE:
hOpenFBut=CreateWindow(_TEXT("BUTTON"),
NULL,
WS_CHILD|BS_PUSHBUTTON|BS_BITMAP,//WS_CHILD,
238,48,
BUTTON_WIDTH,
BUTTON_HEIGHT,
hWnd,
HMENU(OPENFILE),
GetModuleHandle(NULL),NULL);
ShowWindow(hOpenFBut,SW_SHOW);
hChooseDirBut=CreateWindow(_TEXT("BUTTON"),
NULL,
WS_CHILD|BS_PUSHBUTTON|BS_BITMAP,
238,48+BUTTON_SPACING,
BUTTON_WIDTH,
BUTTON_HEIGHT,hWnd,
HMENU(CHOOSEDIR),
GetModuleHandle(NULL),NULL);
ShowWindow(hChooseDirBut,SW_SHOW);
hForwBut=CreateWindow(_TEXT("BUTTON"),
NULL,
WS_CHILD|BS_PUSHBUTTON|BS_BITMAP,
700,570,
BUTTON_WIDTH,
BUTTON_HEIGHT,hWnd,
HMENU(FORWARD),
GetModuleHandle(NULL),NULL);
ShowWindow(hForwBut,SW_SHOW);
hBackwBut=CreateWindow(_TEXT("BUTTON"),
NULL,
WS_CHILD|BS_PUSHBUTTON|BS_BITMAP,
400,570,
BUTTON_WIDTH,
BUTTON_HEIGHT,hWnd,
HMENU(BACKWARD),
GetModuleHandle(NULL),NULL);
ShowWindow(hBackwBut,SW_SHOW);
hFilesListLb=CreateWindow(_TEXT("LISTBOX"),
_TEXT("Список файлов"),
WS_CHILD,//|LBS_DISABLENOSCROLL ,//|LBS_MULTICOLUMN,
5,180,
170,//BUTTON_WIDTH,
410,//BUTTON_HEIGHT,
hWnd,
HMENU(FILESLIST),
GetModuleHandle(NULL),NULL);
ShowWindow(hFilesListLb,SW_SHOW);
hOpFIc=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_OPFILE));
hChDIc=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_OPDIR));
hForwBIc=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_FORW));
hBackwBIc=LoadBitmap(GetModuleHandle(NULL),MAKEINTRESOURCE(IDB_BACKW));
SendMessage(hOpenFBut,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hOpFIc);
SendMessage(hChooseDirBut,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hChDIc);
SendMessage(hForwBut,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hForwBIc);
SendMessage(hBackwBut,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hBackwBIc);
//dwErr=GetLastError();
//swprintf(txt,10,L"%d",dwErr);
//MessageBox(0,txt,_TEXT(" "),MB_OK);
UpdateWindow(hOpenFBut);
GraphFiles.AddFilter(_TEXT(".BMP"));
GraphFiles.AddFilter(_TEXT(".JPEG"));
GraphFiles.AddFilter(_TEXT(".JPG"));
GraphFiles.AddFilter(_TEXT(".TIFF"));
GraphFiles.AddFilter(_TEXT(".GIF"));
GraphFiles.AddFilter(_TEXT(".PNG"));
ofnOpenGr.lStructSize=sizeof(OPENFILENAME);
ofnOpenGr.lpstrFile=FullPath;
ofnOpenGr.nMaxFile=MAX_FULL_PATH_LEN;
ofnOpenGr.lpstrFileTitle=FileName;
ofnOpenGr.nMaxFileTitle=MAX_FILENAME_LEN;
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case OPENFILE:
if(GetOpenFileName(&ofnOpenGr))
{
//MessageBox(hWnd,FullPath,FileName,MB_OK);
SendMessage(hFilesListLb,LB_ADDSTRING,0,(LPARAM)FileName);
GraphFiles.AddFile(FullPath);
}
lListIndex++;
SendMessage(hFilesListLb,LB_SETCURSEL,(WPARAM)lListIndex,0);
InvalidateRect(hWnd,&clRect,TRUE);
UpdateWindow(hWnd);
break;
case CHOOSEDIR:
iList=SHBrowseForFolder(&biPath);
SHGetPathFromIDList(iList,FullPath);
GraphFiles.AddGroupOfFiles(FullPath);
for(long i=0; i<GraphFiles.GetFilesListSize();i++)
SendMessage(hFilesListLb,LB_ADDSTRING,0,
(LPARAM)GraphFiles.GetShortNameByIndex(i));
lListIndex=0;
SendMessage(hFilesListLb,LB_SETCURSEL,lListIndex,0);
InvalidateRect(hWnd,&clRect,TRUE);
UpdateWindow(hWnd);
break;
case FORWARD:
if(lListIndex<GraphFiles.GetFilesListSize()-1)
lListIndex++;
else lListIndex=0;
SendMessage(hFilesListLb,LB_SETCURSEL,lListIndex,0);
InvalidateRect(hWnd,&clRect,TRUE);
UpdateWindow(hWnd);
break;
case BACKWARD:
if(lListIndex)
lListIndex--;
else lListIndex=0;
SendMessage(hFilesListLb,LB_SETCURSEL,lListIndex,0);
InvalidateRect(hWnd,&clRect,TRUE);
UpdateWindow(hWnd);
break;
case FILESLIST:
InvalidateRect(hWnd,&clRect,TRUE);
UpdateWindow(hWnd);
break;
}
break;
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
GetClientRect(hWnd,&clRect);
Paint(hdc,&clRect,GraphFiles[lListIndex], hWnd);
EndPaint(hWnd, &ps);
break;
case WM_SIZING:
rWinSize=(RECT*)lParam;
if(rWinSize->right>MaxWidth)
{
rWinSize->right=MaxWidth;
CurWidth=MaxWidth;
}
if(rWinSize->bottom>MaxHeight)
{
rWinSize->bottom=MaxHeight;
CurHeight=MaxHeight;
}
if(rWinSize->right<MinWidth)
{
rWinSize->right=MinWidth;
CurWidth=MinWidth;
}
if(rWinSize->bottom<MinHeight)
{
rWinSize->bottom=MinHeight;
CurHeight=MinHeight;
}
else
{
CurHeight=rWinSize->bottom;
CurWidth=rWinSize->right;
}
SetWindowPos(hOpenFBut,HWND_TOP,
(int)((double)CurWidth/RELATIVE_X_OPForDBUTTON_COORD),
(int)((double)CurHeight/RELATIVE_Y_OPForDBUTTON_COORD),
BUTTON_WIDTH,BUTTON_HEIGHT,SWP_SHOWWINDOW);
SetWindowPos(hChooseDirBut,HWND_TOP,
(int)((double)CurWidth/RELATIVE_X_OPForDBUTTON_COORD),
(int)((double)CurHeight/RELATIVE_Y_OPForDBUTTON_COORD)+BUTTON_SPACING,
BUTTON_WIDTH,BUTTON_HEIGHT,SWP_SHOWWINDOW);
SetWindowPos(hForwBut,HWND_TOP,
(int)((double)CurWidth*0.7),
(int)((double)(CurHeight-CurHeight/6.2)),
BUTTON_WIDTH,BUTTON_HEIGHT,SWP_SHOWWINDOW);
SetWindowPos(hBackwBut,HWND_TOP,
(int)((double)CurWidth*0.4),
(int)((double)(CurHeight-CurHeight/6.2)),
BUTTON_WIDTH,BUTTON_HEIGHT,SWP_SHOWWINDOW);
SetWindowPos(hFilesListLb,HWND_TOP,
(int)((double)CurWidth*0.005),
(int)((double)(CurHeight-CurHeight/1.36)),
(int)((double)CurWidth*0.17),
(int)((double)(CurHeight-CurHeight/2.5)),
SWP_SHOWWINDOW);
break;
case WM_SYSCOMMAND:
switch(LOWORD(wParam))
{
case SC_MAXIMIZE:
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void Paint(HDC hdc, const RECT* rect, TCHAR* tFileName, HWND hWnd)
{
#define VERT_DIVIZOR 5
#define HOR_SPLITTER_DIVIZOR 4
#define IMAGE_BORDER_DIVIZOR 5
#define RIGHT_BORDER 3.5
#define BOTTOM_BORDER 3.5
#define INFO_LEN 50
TCHAR tTitle[]=_TEXT("Выберите изображение для просмотра:");
TCHAR tInfoStr1Title[]=_TEXT("Имя файла: ");
TCHAR tInfoStr2Title[]=_TEXT("Тип файла: ");
TCHAR tInfoStr3Title[]=_TEXT("Размер: ");
TCHAR tInfoStr1[INFO_LEN];
TCHAR tInfoStr2[INFO_LEN];
TCHAR tInfoStr3[INFO_LEN];
TCHAR tBuf1[INFO_LEN], tBuf2[INFO_LEN];
TCHAR tFList[]=_TEXT("Cписок файлов: ");
int iVLine=(int)((double)(rect->right/VERT_DIVIZOR));
int iHorSplitLine=(int)((double)(rect->bottom/HOR_SPLITTER_DIVIZOR));
WIN32_FILE_ATTRIBUTE_DATA FileData;
Graphics graph(hdc);
Pen MainPen(Color::Silver,3);
Pen BorderPen(Color::OrangeRed,3);
StringFormat Format;
Format.SetAlignment(Gdiplus::StringAlignmentNear);//StringAlignment);
Format.SetLineAlignment(StringAlignmentNear);
Font mainFont(_TEXT("Arial"),22,FontStyleItalic);
Font suppFont(_TEXT("Arial"),8,FontStyleItalic);
RectF clRect((REAL)rect->left,(REAL)rect->top,
(REAL)rect->right,(REAL)rect->bottom);
LinearGradientBrush GrBrush(clRect,Color(130,255,0,0),
Color(255,0,0,255),
LinearGradientModeBackwardDiagonal);
SolidBrush BgBrush(Color::LightGray);
graph.FillRectangle(&BgBrush,clRect);
RectF TitleRect((REAL)iVLine+50,10,(REAL)rect->right,20+22);
RectF InfoRect1((REAL)10,10,(REAL)iVLine-5,16);
RectF InfoRect2((REAL)10,36,(REAL)iVLine-5,16);
RectF InfoRect3((REAL)10,62,(REAL)iVLine-5,16);
RectF FilesListRect((REAL)10,iHorSplitLine+10,(REAL)iVLine-5,16);
graph.DrawString(tTitle,sizeof(tTitle)/sizeof(TCHAR)-1,
&mainFont,TitleRect,&Format,&GrBrush);
graph.DrawString(tFList,sizeof(tFList)/sizeof(TCHAR)-1,
&suppFont,FilesListRect,&Format,&GrBrush);
if(tFileName==NULL)
{
graph.DrawString(tInfoStr1Title,sizeof(tInfoStr1Title)/sizeof(TCHAR)-1,
&suppFont,InfoRect1,&Format,&GrBrush);
graph.DrawString(tInfoStr2Title,sizeof(tInfoStr2Title)/sizeof(TCHAR)-1,
&suppFont,InfoRect2,&Format,&GrBrush);
graph.DrawString(tInfoStr3Title,sizeof(tInfoStr3Title)/sizeof(TCHAR)-1,
&suppFont,InfoRect3,&Format,&GrBrush);
}
else
{
GetFileAttributesEx(tFileName,GetFileExInfoStandard,&FileData);
lstrcpy(tInfoStr3,tInfoStr3Title);
swprintf(tBuf1,10,L"%d",FileData.nFileSizeLow);
lstrcat(tInfoStr3,tBuf1);
lstrcat(tInfoStr3,_TEXT(" байт"));
lstrcpy(tInfoStr2,tInfoStr2Title);
lstrcpyn(tBuf1,PathFindExtension(tFileName),INFO_LEN);
lstrcat(tInfoStr2,tBuf1);
lstrcpy(tInfoStr1,tInfoStr1Title);
lstrcpyn(tBuf1,PathFindFileName(tFileName),INFO_LEN);
lstrcat(tInfoStr1,tBuf1);
graph.DrawString(tInfoStr1,-1,
&suppFont,InfoRect1,&Format,&GrBrush);
graph.DrawString(tInfoStr2,-1,
&suppFont,InfoRect2,&Format,&GrBrush);
graph.DrawString(tInfoStr3,-1,//sizeof(tInfoStr3)/sizeof(TCHAR)-1,
&suppFont,InfoRect3,&Format,&GrBrush);
}
Point VerticalLine[2]={Point(iVLine,0),
Point(iVLine,rect->bottom)};
Point HorSplitLine[2]={Point(0,iHorSplitLine),
Point(iVLine,iHorSplitLine)};
graph.DrawLines(&BorderPen,VerticalLine,
sizeof(VerticalLine)/sizeof(Point));
graph.DrawLines(&BorderPen,HorSplitLine,
sizeof(HorSplitLine)/sizeof(Point));
RectF PictureBorder((REAL)iVLine+50,(REAL)((int)((double)(rect->bottom/IMAGE_BORDER_DIVIZOR))+10),
(REAL)(rect->right-((int)((double)(rect->right/RIGHT_BORDER)))),
(REAL)(rect->bottom-((int)((double)(rect->bottom/BOTTOM_BORDER)))));
graph.DrawRectangle(&MainPen,PictureBorder);
if(tFileName==NULL)
{
graph.FillRectangle(&SolidBrush(Color::WhiteSmoke),
PictureBorder);
}
RECT PicRect;
if(tFileName!=NULL)
{
Image img(tFileName);
graph.DrawImage(&img,PictureBorder);
}
Файл GdiPlusLoader.cpp
#include "stdafx.h"
#include "GdiPlusLoader.h"
#pragma comment(lib,"gdiplus.lib")
#ifndef DEBUG
#pragma comment(lib,"gdiplus.lib")
//#pragma comment(linker,"/delayload:gdiplus.dll")
#endif
namespace AdvDrawing
{
GDIPlusLoader::GDIPlusLoader()
{
bSuccessInit=true;
Gdiplus::GdiplusStartupInput gdipInput;
__try
{
Gdiplus::GdiplusStartup(&upToken,&gdipInput,0);
}
__except(1)
{
bSuccessInit=false;
}
}
GDIPlusLoader::~GDIPlusLoader()
{
if(bSuccessInit) Gdiplus::GdiplusShutdown(upToken);
}
}
Windows приложение для просмотра графических файлов