2009-12-04 2 views
0

Я хочу создать форму, но просто используйте ее для сохранения изображения. (Как и в виде брызг)Delphi + Прозрачные формы с родителями

Для того, чтобы создать форму, как это я использую эти строки:

SetWindowLong(Handle, GWL_EXSTYLE, LexStyle or WS_EX_LAYERED); 
UpdateLayeredWindow(Handle, 0, nil, @LBitmapSize, LBitmap.Canvas.Handle, 0, 
    @LBlendFunction, ULW_ALPHA); 

Это изображение является PNG изображения с прозрачным слоем.

Форма должна иметь родительскую форму или иметь поведение формы, имеющей ее.

В этом проблема, если я добавлю какой-либо компонент в эту форму, это просто не отображает компонент. И если я устанавливаю для него родительскую форму, это теряет прозрачность.

Но мне нужно добавить компоненты в это, и мне нужно установить родительский элемент в форму.

Кто-нибудь знает, как это сделать?

+0

Предпоследний абзац не анализируется как английский. Пожалуйста, перефразируйте его. –

ответ

2

Вы можете попробовать установить не Parent свойства напрямую, а с помощью подклассов ...

Пусть TParentForm является родительской формой и TAlphaForm является формой с изображением.

При создании экземпляра TAlphaForm передайте экземпляр параметра TParentForm as Owner и измените WndProc формы владельца в конструкторе.

Далее приведен пример кода для TAlphaForm:

type 
    TAlphaForm = class(TForm) 
    private 
    FParentWndProc : TWndMethod; 
    FParentForm : TCustomForm; 

    procedure HookWindowProc(var Message: TMessage); 

    public 
    constructor Create(AOwner : TComponent); override; 
    destructor Destroy; override; 
    end; 

Реализация:

constructor TAlphaForm.Create(AOwner: TComponent); 
begin 
    inherited; 

    if(Assigned(AOwner) and (Owner is TCustomForm)) then begin 

    FParentForm := TCustomForm(Owner); 
    // Subclass owner window 
    FParentWndProc := FParentForm.WindowProc; 
    FParentForm.WindowProc := HookWindowProc; 
    // Need to repaint to show initial picture 
    if(FParentForm.HandleAllocated) then FParentForm.Invalidate; 

    end else begin 

    FParentForm := nil; 
    FParentWndProc := nil; 

    end; 

end; 

destructor TAlphaForm.Destroy; 
begin 
    if(Assigned(FParentForm)) then begin 
    // Restore original WndProc and repaint to restore original look if available 
    FParentForm.WindowProc := FParentWndProc; 
    if(FParentForm.HandleAllocated) then FParentForm.Invalidate; 
    FParentForm := nil; 
    FParentWndProc := nil; 
    end; 
    inherited; 
end; 

procedure TAlphaForm.HookWindowProc(var Message: TMessage); 
begin 

    if(not (Assigned(FParentForm) and Assigned(FParentWndProc))) 
    then exit; 

    FParentWndProc(Message); 

    if(Message.Msg = WM_PAINT) then begin 
    // Paint alpha image here on Owner's form canvas 
    // Here is sample painting 
    FParentForm.Canvas.Pen.Width := 3; 
    FParentForm.Canvas.Pen.Color := clRed; 
    FParentForm.Canvas.Ellipse(FParentForm.ClientRect); 
    end else if(Message.Msg = WM_SIZE) then begin 
    // Needed because the whole form must be repainted 
    FParentForm.Invalidate; 
    end; 

end; 

Для меня решение работает с этим родителем кода формы:

type 
    TForm1 = class(TForm) 
    Button2: TButton; 
    Button3: TButton; 
    procedure Button2Click(Sender: TObject); 
    procedure Button3Click(Sender: TObject); 
    private 
    { Private declarations } 
    FAlpha : TForm; 
    public 
    { Public declarations } 
    constructor Create(AOwner : TComponent); override; 
    end; 

Реализация:

procedure TForm1.Button2Click(Sender: TObject); 
begin 
    if(not Assigned(FAlpha)) then FAlpha := TAlphaForm.Create(Self); 
end; 

procedure TForm1.Button3Click(Sender: TObject); 
begin 
    FreeAndNil(FAlpha); 
end; 

constructor TForm1.Create(AOwner: TComponent); 
begin 
    inherited; 
    FAlpha := nil; 
end; 
0

Предполагая, что обе формы внутри одного приложения вы пытаетесь создать общедоступный метод, который может действовать как обработчик ваших опций? Что-то вроде:

function TForm1.UpdateForm(Action: Integer/[Enumerated Type]/[etc]; Parameters: TStringList): Boolean;

с соответствующим кодом обработки внутри должны получить, что вам нужно без необходимости прибегать к API обратных вызовов или требующих информации ручки.

+0

Я понятия не имею, о чем это говорит. На какой вопрос вы ответили? –

+0

То, как я понимаю исходный вопрос, заключается в том, что разработчик хочет иметь «контрольную» форму и «дисплейную» форму, которая покажет изображение после того, как он будет управляться элементом управления. Возможно, что-то вроде многоформатного редактора изображений или дисплея караоке? –

2

Вы не можете использовать стиль WS_EX_LAYERED для дочерних окон, таких как форма с назначенным родителем. Вместо этого вам придется использовать SetWindowRgn().

+0

Я пробовал, но это не совсем то, что мне нужно. Форма должна изменяться по мере необходимости на основе изменения другой формы. Как будто это был его родитель. –

+0

hun ...хорошо Я собираюсь проверить это –

+0

Я установил SetWindowRgn, но он не ограничивал ограничения формы, может быть, некоторые вещи я делаю неправильно? –

Смежные вопросы