IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> RTPatch 8.0, Отображение кириллицы и пр.
Siberian GRemlin
Jul 12 2008, 16:57
Сообщение #1


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



1. Думаю все знакомы с данной продукцией -- сталкивались с обновлениями для некоторых игр, созданных с помощью данной программы. Я тоже ей пользуюсь в тех же целях (в этом есть крайняя необходимость и посему советовать другое ПО не стоит). Проблема в том, что если написать текст приветствия (выводится при запуске откомпилированного обновления) на русском, то по-русски там ничего не будет, а будут "крякозябры". Посоветуйте, как побороть данный недуг и заставить программу выводить текст на русском. Если необходимо -- выложу примеры.

2. В дистрибутиве также идёт пример на сях и дельфях с использованием patchw32.dll т.е. как в свою прогу добавить поддержку обновления файлов из файло-обновления [.RTP], но что-то либо я переучился, либо одно из двух, но я не могу разобраться...


P.S.: Если знаете где взять версию свежее 8.0 -- буду признателен.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 12 2008, 17:10
Сообщение #2


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Siberian GRemlin!
В программе ни разу не создавал свои патчи, но попробуй вставить русский текст в UNICODE или UTF-8.

Ещё когда-то давно какую-то программу руссифицировал, так там русский текст не отображался, пока в ресурсах диалогов не указал параметры шрифта (где-то даже читал, что нужно указать правильный язык и шрифт, который его поддерживает - тогда всё выведется). Какие указывал тогда уже не помню - сейчас глянул для примера Lines'98 через ResHacker - там в парметрах такое стоит:
CODE
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
FONT 8, "MS Sans Serif"
Может здесь тоже надо исправить?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Jul 25 2008, 12:45
Сообщение #3


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Разобрался я как работать с patchw32.dll и даже подключил его в InnoSetup, только этот гад выдаёт ошибку (№15), что файл для обновления не найден. Пробовал и так и сяк -- не хочет. Хотя, прога на дельфях в тех же условиях работает отлично.
P.S.: До этого выдавал 36-ую ошибку -- убрал пробел в пути для установки и заработало.

Возможно, проблема в этом:
Поскольку в InnoSetup нету типа pointer, да и многого другого, то пришлось вырезать функцию CallBack и заменить её на pChar. Может я затупил, вот исходник проги на дельфях (форма с кнопкой и строкой ввода):
CODE
unit Main;
interface
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

type
  TMainForm = class(TForm)
    InputField: TEdit;
    Label1: TLabel;
    Apply: TButton;
    Cancel: TButton;
    procedure ApplyClick(Sender: TObject);
    procedure CancelClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  MAX_MESSAGES = 10;   { Max number of messages to process at any one time}

var
  MainForm: TMainForm;
  CallBackProc: TFarProc;
  hWND: THandle;

  ReOpenBuf: TOFStruct; { some variables for our output file}
  Output: file;
  FileId: Integer;


{ Declare the CallBack function.  If we are compiling in a 32-bit
  world, we need to declare the CallBack as stdcall }
function CallBack (id: Cardinal; lpParm: pointer): pchar;
  export;
{$IFDEF WIN32}
stdcall;
{$ENDIF}

{ Declare the RTPatchApply32 function, depending on the platform, this
  may be RTPatchApply or RTPatchApply32 }
{$IFDEF WIN32}
function RTPatchApply32 ( cmdLine: pChar; CallBack: pointer;
WaitFlag: boolean ): word; stdcall;
{$ELSE}
function RTPatchApply ( cmdLine: pChar; CallBack: pointer;
WaitFlag: boolean ): word;
{$ENDIF}

implementation

{ Declare the RTPatchApply function }
{$IFDEF WIN32}
function RTPatchApply32; external 'patchw32.dll'
  name 'RTPatchApply32@12';
{$ELSE}
function RTPatchApply; external 'patchw';
{$ENDIF}

{$R *.DFM}

{ called when the user clicks 'apply' }
procedure TMainForm.ApplyClick(Sender: TObject);
var
  cmdLine: pChar;
  retCode: short;

begin
  { Allocate space for the cmdLine, copy it from the edit box of the
    MainForm, and call RTPatchapply with that commandLine }
  cmdLine:= strAlloc(255);
  MainForm.InputField.GetTextBuf(cmdLine, 255);

{$IFDEF WIN32}
  retCode:= RTPatchApply32(cmdLine, @CallBack, TRUE);
{$ELSE}
  retCode:= RTPatchApply(cmdLine, @CallBack, TRUE);
{$ENDIF}

  { Display the retCode of RTPatchApply32. You should use the
    documentation provided to determine the cause of a specific retcode.
    Zero indicates success. }
  MessageDlg('RTPatchApply32 returned a value of: ' +
            IntToStr (retCode) +  #10#13#10#13 +
            'You should use this value to provide feedback to your end-user.',
            mtInformation,
            [mbOK],
            0);

  { Free some variables and quit }
  strDispose (cmdLine);
  Application.Terminate;

end;

{ This sample CallBack function has little functionality.  It is provided
  to demonstrate the syntax for the CallBack that RTPatchApply expects.
  Our example Aborts on many IDs.  You would need to add something
  reasonable in place of the command 'result:= NIL;' In most cases
  you can get to the lpParm parameter by typecasting to a pChar.
  For ID0013, it is necessary to access two string pointers, thus
  you will have to do the following:
    TYPE
      Tarray=array[0..1] of pChar;
      Locarray=^Tarray;

  You can then access the first string with LocArray(lpParm)^[0]
    and the second field with LocArray(lpParm)^[1]
}
function CallBack (Id: Cardinal; lpParm: pointer) : pChar;
type
  Tarray = array[0..1] of pChar;
  Locarray= ^Tarray;

var
  msg: TMsg;
  MsgCount: Integer;
  sysName: pChar;
  sysLoc: pChar;

begin

  result:= '';

  { Do some message processing while we are here }
  for  MsgCount := MAX_MESSAGES DOWNTO 0 DO
  begin
    if (PeekMessage( msg, hWND, 0, 0, PM_REMOVE ) = false) then
      break;
    TranslateMessage( msg );
    DispatchMessage( msg );
  end;

  case id of

    1..4: { Print some warning/error messages to a file }
        _lwrite(FileId, pChar(lpParm), strLen(pChar(lpParm)));

   { 5: } { % Complete THIS file (not entire patch process % complete)
         Here you may want to update a progress meter, or otherwise
         let your customer know that some kind of progress is being
         made.

         Note that lpParm is a far pointer to a 16-bit unsigned integer,
         Thus the way to access the % complete for the current file is:
         percComplete := word(lpParm^)

         The range for percComplete would be 0x0000 .. 0x8000
         or 0 .. 32768 (Base10)
         }

   { 6: } { Number of patch files to patch
            This number may be useful to determine a rough estimate
            on percent complete for entire patch process

            Note that lpParm is a far pointer to a 32-bit Integer,
            Thus the way to access the number of patch files is to
            use: numPatchFiles := longint(lpParm^)
            }

   { 7: } { Patch file start
            Use to inform user which file is being patched }

   { 8: } { Current file patch Complete }

     9: { Print a progress message }
       _lwrite(FileId, pChar(lpParm), strLen(pChar(lpParm)));

    10:  { Print a help message }
       _lwrite(FileId, pChar(lpParm), strLen(pChar(lpParm)));

    11:  { Print a patch file comment }
       _lwrite(FileId, pChar(lpParm), strLen(pChar(lpParm)));

    12: { Print Copyright Information
          You may choose to substitute your own copyright information
          at this point}
       _lwrite(FileId, pChar(lpParm), strLen(pChar(lpParm)));

    13:  { Patch File dialog
             Occurs when the indicated patch file can not be found, or
             no patch file name was provided.  Set result to the full
             path to the patch file.  For now, abort the patch. }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 13', 16);
        end;

    14: { Invalid patch file alert
          Insert messages about contacting technical support here.
          For now, just abort the patch }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 14', 16);
        end;

    15: { Password Dialog
          (If patch file is password protected) return pointer to
          password.  For now, dont allow this.  Abort patch. }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 15', 16);
        end;

    16: { Invalid password alert
          Prompt user for password again.  We shouldn't get here
          since we abort on password dialog }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 16', 16);
        end;

    17: { Next Disk dialog
          If using the split option, then return the disk change string.
          For now, abort the patch. }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 17', 16);
        end;

    18: { Invalid disk alert
          Inserted disk does not contain valid patch files.
          For now abort patch. }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 18', 16);
        end;

    19: { Location confirmation dialog
            If using SYSTEMTAGs and confirm, allow user to
            accept/deny the system location.  Our CallBack
            always accepts : 'YES'
          Note that the variables sysName and sysLoc hold
            the system information. }
        begin
          sysName:= stralloc(255);
          sysLoc:= strAlloc (255);
          strCopy (sysName, LocArray(lpParm)^[0]);
          strCopy (sysLoc, LocArray(lpParm)^[1]);

     { ... Do something here. Possibly display the
       system info contained in sysName and sysLoc ... }

          Result:= 'Y';     { Accept system Location }
          strDispose (sysName);
          strDispose (sysLoc);
        end;

    20: { Location dialog
          If system is not found, then have the user supply patch
          with that location.  Return full path to the system location.
          For now, simply abort the patch. }
        begin
          Result:= NIL;
          _lwrite(FileId, 'Aborted on ID 20', 16);
        end;

  { 21: } { Idle CallBack
            Included to provide Message dispatching and to keep
            the system responsive to the user }

  { 22: } {Searching for system CallBack }

  end;

  { Do some more message processing while we are here }
  for  MsgCount := MAX_MESSAGES DOWNTO 0 DO
  begin
    if (PeekMessage( msg, hWND, 0, 0, PM_REMOVE ) = false) then
      break;
    TranslateMessage( msg );
    DispatchMessage( msg );
  end;

  { The contents of Result are often not used, but in all cases
    returning a NIL value in Result will Abort the patch.  Thus if
    the return value is not used, and the patching should continue,
    you should assign Result to '', or some other non-NIL value. }

end;

{ If user selects 'Cancel' just kill the application }
procedure TMainForm.CancelClick(Sender: TObject);
begin
  application.Terminate;
end;


{ Startup stuff:
    Get a handle for the output file
    Get a handle for the application to do message
      processing. }
begin
  fileId := OpenFile('Patch.log', ReOpenBuf, OF_CREATE);
  if (fileId = -1) then
    raise exception.create('Unable to open output file.');
  hWND:= Application.Handle;
end.


Что вообще эта функция делает, кроме того как пишет в текстовик информацию о состоянии? В InnoSetup вызывается просто:
CODE
var
    retCode: word;
    CallBack: pChar;
begin
    if FileExists(ExpandConstant('{app}\VQA1.MIX')) then retCode:=RTPatchApply32(ExpandConstant('{app}\VQA1.RTP'), CallBack, TRUE)
            else MsgBox('Файл не найден', mbInformation, MB_OK);
end;
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 25 2008, 14:41
Сообщение #4


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Ох... разбираться в этом.
Навскидку - вместо PChar попробуй Cardinal, только перед этим присвой ей ноль (типа NULL-указатель будет). Вот так как-нибудь:
CODE
var
    retCode: word;
    CallBack: Caridnal;
begin
  CallBack:=0;
  if FileExists(ExpandConstant('{app}\VQA1.MIX')) then
    retCode:=RTPatchApply32(ExpandConstant('{app}\VQA1.RTP'), CallBack, TRUE)
  else
    MsgBox('Файл не найден', mbInformation, MB_OK);
end;

Кстати, в примерах (CodeDll.iss) вместо PChar используют String:
CODE
function MessageBox(hWnd: Integer; lpText, lpCaption: String; uType: Cardinal): Integer;
external 'MessageBoxA@user32.dll stdcall';

Может тебе тоже стоит попробовать?
CODE
function RTPatchApply32(cmdLine: String; CallBack: Cardinal; WaitFlag: boolean): Word;
external 'RTPatchApply32@12@patchw32.dll stdcall';
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Siberian GRemlin
Jul 26 2008, 13:04
Сообщение #5


Advanced Member
***

Группа: CTPAX-X
Сообщений: 533
Регистрация: 4-February 08
Пользователь №: 2
Спасибо сказали: 221 раз(а)



Не помогло, к сожалению.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Jul 27 2008, 05:23
Сообщение #6


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Слушай, а в RTPatchApply32 не указывается каталог в котором лежат необходимые файлы. Как тогда она их находит? В текущем ищет? Попробуй тогда ещё сменить его перед исправлением:
CODE
SetCurrentDir(ExpandConstant('{app}'));

Может тогда найдёт.


Спасибо сказали:
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 29th March 2024 - 06:07