Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1264
Благодарности: 1024

Профиль | Отправить PM | Цитировать


Цитата Kashtan007:
Как место серых окон (Inner Notebook и Inner Page) на страницах установщика поставить изображение (фон)? »
Способов несколько:
1. Самый распространенный способ - скрыть OuterNotebook, влепить фоновую картинку на форму, сверху создать аналоги скрытых статиков (TNewStaticText -> TLabel), менять родителя остальных контролов (TBitmapImage, TEdit, TNewCheckListBox и т.д.) в нужное время для имитации перехода между страницами.
2. Сабклассинг. Переопределить оконные процедуры WizardForm, страниц OuterNotebook (включая вложенные) на свои и отрисовывать фон самому. В TWizardForm и TNewNotebookPage фон рисуется с помощью системной кисти цвета clBtnFace, которую можно представить как узорчастую кисть цвета clBtnFace размером в 1х1 пикселя. Имея картинку, можно создать узорчастую кисть на ее основе, и рисовать фон ею вместо системной в своей оконной процедуре. В примере создается кисть на основе картинки (я не стал создавать кисть на основе картинки с размерами клиентской части формы, взял WizardSmallBitmapImage, чтобы увидеть воочию как система заливает фон кистью), переопределяются оконные процедуры для TWizardForm и TNewNotebookPage, в оконных процедурах фон рисуется созданной кистью при получении сообщения WM_ERASEBKGND.
читать дальше »

Код: Выделить весь код
[Setup]
AppName=test
AppVerName=test
DefaultDirName={tmp}
CreateAppDir=no
Uninstallable=no
CreateUninstallRegKey=no

[Languages]
Name: ru; MessagesFile: compiler:Languages\russian.isl

[code]
#define A = (Defined UNICODE) ? "W" : "A"
const
    GWL_USERDATA = (-21);
    GWL_WNDPROC = (-4);
    WM_ERASEBKGND = $0014;
    GA_ROOT = 2;

var
    g_hBackgroundBrush: THandle;
    g_pWndProc, g_pNotebookPageWndProc: Longint;

function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; external 'GetWindowLong{#A}@user32.dll stdcall';
function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLong{#A}@user32.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam: Longint; lParam: Longint): Longint; external 'CallWindowProc{#A}@user32.dll stdcall';
function CreatePatternBrush(hbmp: HBITMAP): THandle; external 'CreatePatternBrush@gdi32.dll stdcall';
function DeleteObject(hObject: THandle): BOOL; external 'DeleteObject@gdi32.dll stdcall';
function GetUpdateRect(hWnd: HWND; var lpRect: TRect; bErase: BOOL): BOOL; external 'GetUpdateRect@user32.dll stdcall';
function GetAncestor(hwnd: HWND; gaFlags: UINT): HWND; external 'GetAncestor@user32.dll stdcall';
function FillRect(hDC: Longint; const lprc: TRect; hbr: Longint): Integer; external 'FillRect@user32.dll stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external 'MapWindowPoints@user32.dll stdcall';
function SetBrushOrgEx(hdc: Longint; nXOrg, nYOrg: Integer; var lppt: TPoint): BOOL; external 'SetBrushOrgEx@gdi32.dll stdcall';

//////////////////////////////////////////////////////////////////////////
function WndProc(hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint;
var
    rc: TRect;
begin
    case Msg of
        WM_ERASEBKGND: begin
            GetUpdateRect(hWnd, rc, False);
            FillRect(wParam, rc, g_hBackgroundBrush);
            Result := 1;
        end;
    else
        Result := CallWindowProc(GetWindowLong(hWnd, GWL_USERDATA), hWnd, Msg, wParam, lParam);
    end;
end;

//////////////////////////////////////////////////////////////////////////////////////
function NotebookPageWndProc(hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint;
var
    pt: TPoint;
    rc: TRect;
begin
    case Msg of
        WM_ERASEBKGND: begin
            MapWindowPoints(hWnd, GetAncestor(hWnd, GA_ROOT), pt, 1);
            SetBrushOrgEx(wParam, -pt.x, -pt.y, pt);
            GetUpdateRect(hWnd, rc, False);
            FillRect(wParam, rc, g_hBackgroundBrush);
            Result := 1;
        end;
    else
        Result := CallWindowProc(GetWindowLong(hWnd, GWL_USERDATA), hWnd, Msg, wParam, lParam);
    end;
end;

//////////////////////////////////////////////////////////
procedure SubclassControlProc(const Control: TWinControl);
var
    i: Integer;
begin
    for i := 0 to Control.ControlCount-1 do if Control.Controls[i] is TWinControl then
    begin
        // subclass notebook page
        if Control.Controls[i] is TNewNotebookPage then with TNewNotebookPage(Control.Controls[i]) do
            if GetWindowLong(Handle, GWL_USERDATA) = 0 then
                SetWindowLong(Handle, GWL_USERDATA, SetWindowLong(Handle, GWL_WNDPROC, g_pNotebookPageWndProc));

        if TWinControl(Control.Controls[i]).ControlCount > 0 then
            SubclassControlProc(TWinControl(Control.Controls[i]));
    end;
end;

///////////////////////////////////
procedure SubclassWizardFormProc();
begin
    // callback proc
    if g_pWndProc = 0 then g_pWndProc := CallbackAddr('WndProc');
    if g_pNotebookPageWndProc = 0 then g_pNotebookPageWndProc := CallbackAddr('NotebookPageWndProc');

    // subclass WizardForm
    if GetWindowLong(WizardForm.Handle, GWL_USERDATA) = 0 then
        SetWindowLong(WizardForm.Handle, GWL_USERDATA, SetWindowLong(WizardForm.Handle, GWL_WNDPROC, g_pWndProc));

    // subclass controls
    SubclassControlProc(WizardForm);
end;

////////////////////////////////////////////////////////////
procedure UnSubclassControlProc(const Control: TWinControl);
var
    i: Integer;
begin
    for i := 0 to Control.ControlCount-1 do if Control.Controls[i] is TWinControl then
    begin
        // unsubclass notebook page
        if (Control.Controls[i] is TNewNotebookPage) then with TNewNotebookPage(Control.Controls[i]) do
            if GetWindowLong(Handle, GWL_USERDATA) > 0 then
                SetWindowLong(Handle, GWL_WNDPROC, GetWindowLong(Handle, GWL_USERDATA));

        if TWinControl(Control.Controls[i]).ControlCount > 0 then
            UnSubclassControlProc(TWinControl(Control.Controls[i]));
    end;
end;

/////////////////////////////////////
procedure UnSubclassWizardFormProc();
begin
    // unsubclass controls
    UnSubclassControlProc(WizardForm);

    // unsubclass WizardForm
    if GetWindowLong(WizardForm.Handle, GWL_USERDATA) > 0 then
        SetWindowLong(WizardForm.Handle, GWL_WNDPROC, GetWindowLong(WizardForm.Handle, GWL_USERDATA));
end;

/////////////////////////////
procedure InitializeWizard();
begin
    // create pattern brush
    g_hBackgroundBrush := CreatePatternBrush(WizardForm.WizardSmallBitmapImage.Bitmap.Handle);

    // subclass
    SubclassWizardFormProc();
end;

//////////////////////////////
procedure DeinitializeSetup();
begin
    // unsubclass
    UnSubclassWizardFormProc();

    // delete pattern brush
    if g_hBackgroundBrush <> 0 then DeleteObject(g_hBackgroundBrush);
end;

Цитата Shkutu:
Когда доходит до строчки, где происходит вызов функции, падает с ошибкой "Could not call proc". Похоже на ошибку инициализации, но если смотреть в дебагере, то на этот момент все длл уже извлечены.
Не подскажете, в чем может быть проблема? »
Shkutu, с типами параметров что-то напутали в GetCRMUserGuid. Попробуйте сменить PAnsiChar на String.
Это сообщение посчитали полезным следующие участники:

Отправлено: 10:13, 23-05-2014 | #752