Ru-Board.club
← Вернуться в раздел «Программы»

» Inno Setup (создание инсталяционных пакетов)

Автор: geranik
Дата сообщения: 19.04.2008 15:48
6apakyda
[setup]
DisableProgramGroupPage=yes (если в пуске не надо)
[Icons]
Name: "{userdesktop}\имя ярлыка"; Filename: "{app}\Y"; parameters: текст параметров ; IconFilename: "{app}\файл иконки.ico"; WorkingDir: "{app}"; Tasks: desktopicon
[Tasks]
Name: desktopicon; Description: Создать иконку на рабочем столе
[files]
Source: Y; DestDir: {app}\Y

{app} это С:\программа\ (Приблизительно так)
Автор: htuos
Дата сообщения: 19.04.2008 19:23
Victor_Dobrov

Цитата:
О загрузке jpg, png, gif и прочих графических файлов через ImgGdiPlus.dll.
Собрал скрипт, загружающий jpeg-файл как фоновый рисунок. (спасибо Genri)
Но если перемещать окно мастера, то изображение стирается. Как это исправить?

1. а кто ж за тебя окно перерисовывать будет?
2. с gdiplus не будут работать инсталлы в win95/98/me и вроде win2k без framework'a

PS сейчас попробую подправить

Добавлено:
вот так должно работать
[more=скрипт]#define Background "Background.jpg"

[Setup]
AppName=Image Stream
AppVerName=Image Stream
CreateAppDir=false
WindowVisible=true

[Files]
Source: {#Background}; Flags: dontcopy noencryption
Source: ImgGdiplus.dll; Flags: dontcopy noencryption
Source: innocallback.dll; Flags: dontcopy noencryption

[Коде]
type
hDC = Longint;
TSIZE = record
cx: UINT;
cy: UINT;
end;
TProc = function (h:hWnd;Msg,wParam,lParam:Longint):Longint;

const
SRCCOPY = $CC0020;

var
ImageStream: Longint;
Size, MainSize: TSize;
WinDC: hDC;

function GetDC(Wnd: HWnd): hDC; external 'GetDC@user32.dll stdcall';
function ReleaseDC(Wnd: HWnd; DC: hDC): Longint; external 'ReleaseDC@user32.dll stdcall';
function LoadPicture(Sw: TSize; name: PChar): Longint; external '_LoadPicture@8@files:ImgGdiplus.dll stdcall delayload';
procedure StretchImg(LoadedImage, hDC: Longint; dstX, dstY, dstXE, dstYE, srcX, srcY, srcXE, srcYE: integer; dwROP: DWord); external '_StretchImg@44@files:ImgGdiplus.dll stdcall delayload';
procedure ReleaseImg(LoadedImage: Longint); external '_ReleaseImg@4@files:ImgGdiplus.dll stdcall delayload';

function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam: Longint; lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
function DefWindowProc(hWnd: HWND; Msg: UINT; wParam: Longint; lParam: Longint): Longint; external 'DefWindowProcA@user32.dll stdcall';

function CallBackProc(P:TProc;ParamCount:integer):LongWord; external 'wrapcallback@files:innocallback.dll stdcall';

function MainFrmProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
begin
if Msg=$000F then begin
ImageStream:=LoadPicture(SIZE,ExpandConstant('{tmp}\{#Background}'));
WinDC:=GetDC(h);
StretchImg(ImageStream,WinDC,0,0,SIZE.CX,SIZE.CY,0,0,MainSize.CX,MainSize.CY,SRCCOPY);
ReleaseDC(h,WinDC);
ReleaseImg(ImageStream);
end;
Result:=DefWindowProc(h,Msg,wParam,lParam);
end;

procedure InitializeWizard;
begin
ExtractTemporaryFile('{#Background}');
MainForm.BorderStyle:=bsNone;
SIZE.cx:=MainForm.Width;
SIZE.cy:=MainForm.Height;
MainSize.CX:=800;
MainSize.CY:=600;
SetWindowLong(MainForm.Handle,-21,SetWindowLong(MainForm.Handle,-4,CallBackProc(@MainFrmProc,4)));
end;[/more]
Автор: Genri
Дата сообщения: 19.04.2008 22:58
htuos -- а что думаешь по поводу сконвертировать jpg в bmp, а потом использовать bmp штатным образом? Я с графикой не очень дружу, но имхо должно быть достаточно просто. Создать длл-ку с одной функцией. Что-то типа:

procedure jpg2bmp(srcName, destName: PChar); stdcall;
var
bmp: TBitmap;
jpg: TPicture;
begin
jpg:= TPicture.Create;
jpg.LoadFromFile(srcName);

bmp:= TBitmap.Create ;
bmp.assign(jpg.Graphic);
bmp.SaveToFile(destName);
end;
Автор: htuos
Дата сообщения: 19.04.2008 23:26
Genri
я тоже не большой знаток графики
сконвертировать конечно можно, вот только работа с jpg (TPicture) разве не через gdiplus организована? к тому же есть подозрение что будут проблемы со сглаживанием. опять же isxbb существует, есть ли смысл писать тоже самое еще раз?
Автор: 6apakyda
Дата сообщения: 20.04.2008 01:23
А возможно сделать так чтобы не могло установится в определённый католог если там нет каких либо файлов!?
И возможно удаление установочного файла после его установки через какоето время?

Добавлено:
htuos

Цитата:
вот так должно работать
скрипт

Если разрешение экрана большое то картинка получается в левом верхнем углу! Можно это как нибуть поправить?

Автор: htuos
Дата сообщения: 20.04.2008 12:11
6apakyda

Код: MainSize.CX:=800;
MainSize.CY:=600;
Автор: denisska80
Дата сообщения: 20.04.2008 12:33
Подскажите, а как мне сформировать в [code] переменные и передать их в другие секции(files,icon), чтобы в code найти необходимые параметры для запуска файлов и создания иконок?
PS Очень нужно
Автор: Victor_Dobrov
Дата сообщения: 20.04.2008 19:08
Доработал скрипт, показывающий в фоновом окне jpg, gif, png файлы. Теперь размер картинки определяется автоматически. [more=Смотреть код.]
#define Background "Background.jpg"

[Setup]
AppName=Image Stream
AppVerName=Image Stream
CreateAppDir=false
WindowVisible=true
OutputDir=.
WindowShowCaption=false

[Files]
Source: {#Background}; Flags: dontcopy noencryption
Source: compiler:ImgGdiplus.dll; Flags: dontcopy noencryption
Source: compiler:innocallback.dll; Flags: dontcopy noencryption

[Code]
type hDC = Longint;
TSize = record cx: UINT; cy: UINT; end;
TProc = function (h: hWnd; Msg, wParam, lParam: Longint): Longint;

const
SRCCOPY = $CC0020; JFIF = $A5A6A3A4; PNG = $12131617; GIF = $07060908;

var
ImageStream: Longint; Size, ImageSize: TSize; WinDC: hDC; n: Integer;

function GetDC(Wnd: HWnd): hDC; external 'GetDC@user32.dll stdcall';
function ReleaseDC(Wnd: HWnd; DC: hDC): Longint; external 'ReleaseDC@user32.dll stdcall';
function LoadPicture(Sw: TSize; name: PChar): Longint; external '_LoadPicture@8@files:ImgGdiplus.dll stdcall delayload';
procedure StretchImg(LoadedImage, hDC: Longint; dstX, dstY, dstXE, dstYE, srcX, srcY, srcXE, srcYE: integer; dwROP: DWord); external '_StretchImg@44@files:ImgGdiplus.dll stdcall delayload';
procedure ReleaseImg(LoadedImage: Longint); external '_ReleaseImg@4@files:ImgGdiplus.dll stdcall delayload';

function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
function DefWindowProc(hWnd: HWND; Msg: UINT; wParam: Longint; lParam: Longint): Longint; external 'DefWindowProcA@user32.dll stdcall';
function CallBackProc(Proc: TProc; ParamCount: Integer): LongWord; external 'wrapcallback@files:innocallback.dll stdcall';

Function GetImgSize(File: String): TSize; var ImageSize: TSize; FS: TFileStream; SizeMap: array[0..3] of Byte; Str: String;    Begin
Case Uppercase(ExtractFileExt(File)) of
'.GIF':    begin
    SizeMap[0]:= GIF shr 24
    SizeMap[1]:= (GIF shr 16) and $FF
    SizeMap[2]:= (GIF shr 8) and $FF
    SizeMap[3]:= GIF and $FF; end
'.JPG','.JPEG':    begin
    SizeMap[0]:= JFIF shr 24
    SizeMap[1]:= (JFIF shr 16) and $FF
    SizeMap[2]:= (JFIF shr 8) and $FF
    SizeMap[3]:= JFIF and $FF; end
'.PNG':    begin
    SizeMap[0]:= PNG shr 24
    SizeMap[1]:= (PNG shr 16) and $FF
    SizeMap[2]:= (PNG shr 8) and $FF
    SizeMap[3]:= PNG and $FF; end
end;
    FS:= TFileStream.Create(File, fmOpenRead);
for n:= 0 to 3 do begin    Str:= Chr(0)
    FS.Seek(SizeMap[n], soFromBeginning);
    FS.ReadBuffer(Str, 1);
    SizeMap[n]:= Ord(Str[1])
end;
FS.Free;
    ImageSize.CX:= Ord(SizeMap[0]) * $100 + Ord(SizeMap[1]); ImageSize.CY:= Ord(SizeMap[2]) * $100 + Ord(SizeMap[3])
    Result:= ImageSize
End;

Function MainFrmProc(h: hWnd; Msg, wParam, lParam: Longint): Longint;
Begin
if Msg= $F then begin
    ImageStream:= LoadPicture(SIZE,ExpandConstant('{tmp}\{#Background}'));
    WinDC:= GetDC(h);
    StretchImg(ImageStream, WinDC, 0, 0, SIZE.CX, SIZE.CY, 0, 0, ImageSize.CX, ImageSize.CY, SRCCOPY);
    ReleaseDC(h,WinDC);
    ReleaseImg(ImageStream);
end;
    Result:= DefWindowProc(h, Msg, wParam, lParam);
End;

Procedure InitializeWizard;
Begin
    ExtractTemporaryFile('{#Background}');
    Size.cx:= MainForm.Width; Size.cy:= MainForm.Height;
    ImageSize:= GetImgSize(ExpandConstant('{tmp}\{#Background}'))
    SetWindowLong(MainForm.Handle, -21, SetWindowLong(MainForm.Handle,-4, CallBackProc(@MainFrmProc,4)));
End;
[/more]
Автор: Diawer
Дата сообщения: 20.04.2008 20:05
Подскажите возможно сделать в коде,

procedure InitializeWizard();
var
TextLabel : TNewStaticText;
begin
TextLabel := TNewStaticText.Create(WizardForm);
TextLabel.Left := ScaleX(3);
TextLabel.Top := ScaleY(345);
TextLabel.Caption := 'by Neyman';
TextLabel.Parent := WizardForm;
TextLabel.Font.Color := clBlack;
TextLabel.Font.Color := clSilver;
end;

что бы надпись была, как в стандартной "BeveledLabel="
дело в том, что там она выглядит как бы вдавленной.
Автор: elapse
Дата сообщения: 20.04.2008 20:16
Diawer, возможно, допиши:

Код: TextLabel.Enabled := False;
Автор: Andylg
Дата сообщения: 20.04.2008 23:40
Подскажите как сделать, чтобы после токо как скрипт скопирует файлы в директорию X и проинсталит их, чтобы он в конце всех опереций удалил эти же файлы?
Автор: htuos
Дата сообщения: 21.04.2008 00:59
как в инно можно написать такую вещь

Код: Pointer(GetWindowLong(h,-21))
Автор: omals
Дата сообщения: 21.04.2008 07:36
2Andylg
Flags: deleteafterinstall;
Автор: Andylg
Дата сообщения: 21.04.2008 10:14
omals спасибо.
А если надо удалить совершенно другую папку (которая например при русифкации будет лишняя), то как быть?
Автор: omals
Дата сообщения: 21.04.2008 11:52
2Andylg
ну если папка или файл вообше не нужен
то и не копировать его
задаем компоненты
[Components]
Name: "EngFiles"; Description: "english files";
Name: "RusFiles"; Description: "русские файлы";

[Files]
Source: "enfiles\*.*" ; DestDir: "{app}"; Components: EngFiles;
Source: "rufiles\*.*" ; DestDir: "{app}"; Components: RusFiles;

если после инсталяции нужно удалить папку то
[Dirs]
Name: "FolderForDelete"; Flags: deleteafterinstall

или в коде удалять все ненужное
см.в хелп функции
DeleteFile
DelTree
Автор: Raf_SE
Дата сообщения: 21.04.2008 19:29
Можно ли какнить так сделать, чтоб после (или до) установки инсталлятор выдавал сообщение "Введите лицензионный серийный номер игры. %1 Если вы его не имеете, то оставьте поле пустым и нажмите ОК". Если юзер ввел номер, то он бы записывался в реестре, если оставил поле пустым, то в той же директории реестра создавался мой, пиратский ключ.
Автор: firefly2005
Дата сообщения: 22.04.2008 02:20
Кто нибудь из прошедших через это.
Поясните как Uninstall.exe сделать "сборным"- то бишь что бы каждое последующая инсталляция-свой анинсталл писала в один (и единственный)

Uninstallable=yes
UninstallLogMode=append
UpdateUninstallLogAppName=yes - это не помогает.

тут вот писал может быть попонятней об этом.
http://forum.ru-board.com/topic.cgi?forum=5&topic=24767&start=1420#10
Автор: Victor_Dobrov
Дата сообщения: 22.04.2008 15:13
htuos - Благодарю за помощь!

Я исправил ошибку в [more=вашем скрипте]
#define    BeginColor    170*65536 + 148*256 + 70    ;Blue Green Red
#define    FinishColor    180*65536 + 224*256 + 230

[Setup]
AppName=Gradient
AppVerName=Gradient
CreateAppDir=false
OutputDir=.

[Code]
type    hDC= Longint;
var BackgroundForm: TForm; BackgroundImage: TBitmapImage; i: Integer;

function ShowWindow(hWnd, nCmdShow: LongWord): LongWord; external 'ShowWindow@user32.dll stdcall';
function GetSysColor(nIndex: Integer): DWORD; external 'GetSysColor@user32.dll stdcall';
function MulDiv(nNumber, nNumerator, nDenominator: Integer): Integer; external 'MulDiv@kernel32.dll stdcall';
function GetDC(Wnd: HWnd): hDC; external 'GetDC@user32.dll stdcall';
function ReleaseDC(Wnd: HWnd; DC: hDC): Longint; external 'ReleaseDC@user32.dll stdcall';
function SetBkMode(DC: hDC; BkMode: Integer): Integer; external 'SetBkMode@gdi32.dll stdcall';
//    function BitBlt(DestDC: hDC;X,Y,Width,Height:Integer;SrcDC:HDC;XSrc,YSrc:Integer;Rop:DWORD):BOOL; external 'BitBlt@gdi32.dll stdcall';
//    function SelectObject(DC: hDC; p2: LongWord): LongWord; external 'SelectObject@gdi32.dll stdcall';
//    function DeleteDC(DC: hDC): BOOL; external 'DeleteDC@gdi32.dll stdcall';

Function RGB(r, g, b: Longint): Longint; Begin Result:= (r or (g shl 8) or (b shl 16)) End;
Function GetBValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 16) End;
Function GetGValue(rgb: DWord): Byte; Begin Result:= Byte(rgb shr 8) End;
Function GetRValue(rgb: DWord): Byte; Begin Result:= Byte(rgb) End;

Procedure GradientFill(WorkBmp: TBitmapImage; BeginColor, FinishColor: TColor);    var ColorBand: TRect; Begin
    WorkBmp.Bitmap.Width:= WorkBmp.Width;
    WorkBmp.Bitmap.Height:= WorkBmp.Height;
for i:=0 to 255 do begin
    ColorBand.Right:= WorkBmp.Width;
    ColorBand.Top:= MulDiv(i, WorkBmp.Height, 255);
    ColorBand.Bottom:= MulDiv(i+1, WorkBmp.Height, 255);
    WorkBmp.Bitmap.Canvas.Brush.Color:= RGB(GetRValue(BeginColor) + MulDiv(I, GetRValue(FinishColor) - GetRValue(BeginColor), 255-1), GetGValue(BeginColor) + MulDiv(I, GetGValue(FinishColor) - GetGValue(BeginColor), 255-1), GetBValue(BeginColor) + MulDiv(I, GetBValue(FinishColor) - GetBValue(BeginColor), 255-1));
    WorkBmp.Bitmap.Canvas.FillRect(ColorBand);
end;
End;

Procedure BitmapTextOut(WorkBmp: TBitmapImage; Message, FontName: String; Style, Left, Top, Size: Byte; Color: TColor); Begin
    with WorkBmp.Bitmap.Canvas do begin    { позицию шрифта указывать в процентах }
    Font.Color:= clBlack;
    Font.Name:= FontName;
    Case Style of
        1:    Font.Style:= [fsBold]
        2:    Font.Style:= [fsItalic]
        3:    Font.Style:= [fsBold, fsItalic]
    end;
    Font.Height:= (WorkBmp.Width + WorkBmp.Height)/200 *Size    // попытка подстроить шрифт под размер окна
SetBkMode(Handle, 1);
    TextOut(WorkBmp.Width/100*Left, WorkBmp.Height/100*Top, Message);
    Font.Color:= Color;
    TextOut(WorkBmp.Width/100*Left - 2, WorkBmp.Height/100*Top - 2, Message);
end
End;

Procedure BackgroundOnActivate(Sender: TObject); Begin if WizardForm.Visible then WizardForm.Show End;
Procedure BackgroundOnResize(Sender: TObject); Begin
    GradientFill(BackgroundImage, {#BeginColor}, {#FinishColor});
    BitmapTextOut(BackgroundImage, MainForm.Caption, 'Times', 3, 10, 8, 4, clWhite)
End;

Procedure InitializeWizard;
Begin
BackgroundForm:= TForm.Create(nil)
    BackgroundForm.BorderStyle:= bsNone
    BackgroundForm.OnActivate:= @BackgroundOnActivate;
    BackgroundForm.OnResize:= @BackgroundOnResize;
BackgroundImage:= TBitmapImage.Create(BackgroundForm);
    BackgroundImage.Align:= alClient;
    BackgroundImage.Enabled:= False;
    BackgroundImage.Parent:= BackgroundForm;
ShowWindow(BackgroundForm.Handle, sw_ShowMaximized)    // фоновое окно на полный экран
End;

Procedure DeinitializeSetup;
Begin
    BackgroundForm.Free
End;
[/more] (функция RGB), теперь градиент на битмапе рисуется правильно.
Автор: Raf_SE
Дата сообщения: 22.04.2008 18:09
Можно ли в компонентах, какнить отключить меню выбора "Полная установка" "компактная" и "выборочная" ? Пробивал как [more=описано в руководстве][Components]
Name: "eng"; Description: "Английская версия"; Flags: exclusive
Name: "rus"; Description: "Русская версия"; Flags: exclusive

[Types]
Name: "custom"; Description: "Выборочная установка"; Flags: iscustom[/more] от Kindly, но тогда не совсем правильно работает "Flags: fixed" а отказаться от него я не могу.
Автор: htuos
Дата сообщения: 22.04.2008 19:03
Victor_Dobrov
я в сторону RGB даже не посмотрел, т.к. взял ее из исходников дельфи. вот так вот бывает . кстати есть функции, которые позволяют считают ширину символов в пикселях (соответственно и длину теста можно получить). для моноширинных шрифтов все быстро и точно считается. так что вот с этим

Цитата:
попытка подстроить шрифт под размер окна

можно и через них попробовать сделать, если интересно конечно

ЗЫ кстати вот такую вещь в моем скрипте
Код: WorkBmp.Bitmap.Width:= W;
WorkBmp.Bitmap.Height:= H;
Автор: Alex1985
Дата сообщения: 22.04.2008 19:37
Как добавить страницу с 2 радио кнопками\чекбоксами "Новая установка" и "Обновление", и что бы "Обновление" нельзя было выбрать, если не обнаружена установленная программа? Плюс к этому, в случае обновления надо запретить запуск программы из секции [Run].
Для информации: установщик при запуске установленную программу видит, нужно лишь обновить установленные компоненты с минимумом телодвижений
Автор: Raf_SE
Дата сообщения: 23.04.2008 15:46

Цитата:
а сделать этот комбобокс невидимым не пробовал?

Не нужно сразу набрасываться, я паскали не понимаю, посему и спрашиваю более мудрых людей. Вот кстати у меня еще пара несложных вопросов:
1. Что нужно пописать чтобы инсталляха добавляла exe'шник игры в список исключений виндовского Брандмауэра?
2. Как сделать чтобы окно инсталлятора запускалась не посредине экрана, а в правом нижнем углу?
Автор: naben
Дата сообщения: 23.04.2008 19:04
Подскажите, может ли инсталлятор определять классическая или обычная тема Wivndows используется при установке и в зависимости от варианта изменить значение в нужном ini файле?
Автор: Sampron
Дата сообщения: 23.04.2008 20:59

Цитата:
а сделать этот комбобокс невидимым не пробовал?

А так не проще?

[Types]
Name: "full"; Description: "Full installation"; Flags: iscustom

[Components]
Name: "help"; Description: "Help File"; Types: full
Name: "readme"; Description: "Readme File"; Types: full
Name: "readme\en"; Description: "English"; Flags: exclusive
Name: "readme\de"; Description: "German"; Flags: exclusive

Добавлено:
Raf_SE

Цитата:
Как сделать чтобы окно инсталлятора запускалась не посредине экрана, а в правом нижнем углу?

Примерно так:

[Code]
function GetSystemMetrics(nIndex:Integer):Integer;
external 'GetSystemMetrics@user32.dll stdcall';

procedure InitializeWizard();
begin
WizardForm.Left:=GetSystemMetrics(16) - WizardForm.ClientWidth - ScaleX(10)
WizardForm.Top:=GetSystemMetrics(17) - WizardForm.ClientHeight - ScaleY(10)
end;
Автор: Raf_SE
Дата сообщения: 23.04.2008 21:13

Цитата:
А так не проще?

Я же писал, если так делать тогда некорректно работает "Flags: fixed".
Автор: Sampron
Дата сообщения: 23.04.2008 21:29
Raf_SE
[Components]
Name: "program"; Description: "Program Files"; Types: full; Flags: fixed
Автор: Raf_SE
Дата сообщения: 23.04.2008 21:30
Sampron, Меня интересует такой расклад:

[Components]
Name: "Lang"; Description: "Язик"; Flags: fixed;
Name: "Lang\rus"; Description: "Русский"; Flags: exclusive;
Name: "Lang\eng"; Description: "English"; Flags: exclusive;
Автор: Sampron
Дата сообщения: 23.04.2008 22:01
Raf_SE
[Types]
Name: full; Description: Full installation; Flags: iscustom

[Components]
Name: "Lang"; Description: "ЯзЫк"; Flags: fixed; Types: full;
Name: "Lang\rus"; Description: "Русский"; Flags: exclusive;
Name: "Lang\eng"; Description: "English"; Flags: exclusive;
Автор: Raf_SE
Дата сообщения: 23.04.2008 22:28
Sampron спс, все работает.

P.S.
Еще б сказал что нужно пописать чтобы инсталляха добавляла exe'шник игры в список исключений виндовского Брандмауэра, было б вобще супер =)
Автор: Hater_Decay
Дата сообщения: 24.04.2008 00:24
Пара глупых вопросов:
1) Как изменить текст <> в "Требуется как минимум <> МБ свободного места" на странице выбора директории?
2) Как всё-таки сделать чтоб имя деинсталлятора было не unins000.exe (cmd ren не предлагать)

Столько тем по инносетапу уже, и количество страниц растёт как на дрожжах. Корифеи, не задумывались над тем чтоб все более-менее толковые приёмы объеденить в этакую "Хрестоматию пользователя", а то я тут искал книжки хоть какие-то по inno setup и ясное дело не нашёл. Готовые красивые скрипты это конечно хорошо, а вот текст, в котором бы всё более-менее подробно описывалось о процессе создания интсалляции начиная с установки иконки дя сетапа (утрирую, понимайте это как с самих азов) и до заоблачных наворотов типа музыки, текстурированных кнопок и т.п. Понимаю что составлять аткое - дело неблагодарное и трудоёмкое, но объединить грамотные фичи хотя бы со всех топиков в некую брошюру было бы несоизмеримо круто

Страницы: 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667

Предыдущая тема: Поиск в WinDjView


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.