Не отображаются дочерние контролы в TabSheet (CBuilder)

Статус: Offline
Реєстрація: 18.02.2007
Повідом.: 2889
Не отображаются дочерние контролы в TabSheet (CBuilder)

Пишу плагин в виде DLL. Есть базовый PageControl в приложении.
При загрузке в dll передаю указатель на этот PageControl, в котором хочу создать TabSheet с контролами, и добавить потом на PageControl.
Проблема заключается в том, что TabSheet рисутеся, а все что в нем - нет. Если же делать не в dll, то рисуется нормально.
Вот мой код:


info->PluginSheet = new TTabSheet(info->PageControl);
info->PluginSheet->ParentFont = false;
info->PluginSheet->PageControl = info->PageControl;
info->PluginSheet->Caption = "Plugin";
info->PluginSheet->Visible = true;
info->PluginSheet->Name = "Page4";

int i=info->PluginSheet->TabIndex;
info->PluginSheet->PageControl->ActivePage->PageIndex=i;

info->ResultGrid = new TStringGrid(info->PluginSheet);
info->ResultGrid->ParentFont = false;
info->ResultGrid->Name = "SG1";
// info->ResultGrid->ParentWindow = info->PageControl->Pages[info->PageControl->TabIndex]->Handle;
info->ResultGrid->Parent = info->PluginSheet;

где PluginSheet - это закладка создаваемая в библиотеке, а PageControl - создан на форме в DesignTime в основном приложении.
После таких операций вкладка появляется но пустая.

Если же в качестве info->ResultGrid->Parent указать любую вкладку, которая создана также в DesignTime - то контрол на ней отображается нормально.
 
попробуйте скопировать Handle объекта Application приложения в Handle объекта Application бибилиотеки

а почему не используете пакеты (bpl) вместо dll?
 
Как вариант можно попробовать на счет хэндла.
bpl не хочу, во первых это жесткая привязка к борланду, хочется сделать переносимое приложение, что бы запускалось везде. Во вторых надеюсь перенести в будущем под Вижуал Си (надеюсь осилить Win32). MFC не хочу пробовать, C# не катит тут. Часть кода пришла с QNX, туда же в будущем и отправится, а пока выбрал Билдер потому что удобно создавать ГУИ.
 
попробуйте скопировать Handle объекта Application приложения в Handle объекта Application бибилиотеки
Извините это как? С чего бы это у ДЛЛ-ки есть "свой объект Аппликейшн"? Этот объект кагбе один в рамках приложения, а ДЛЛ-ка суть часть приложения.

ТС, поройся в свойствах этих ПейджКонтролов и ТабШитов, найди у кого-нить Draw(), Redraw() или чего-нить похожее и после создания СтрингГрид-а - дерни. То есть заставь парента принудительно перерисоваться, он соответственно раздаст WM_PAINT всем чилдренам. Вдруг поможет. От этих свиней VCL всего можно ожидать.
 
почитайте Марко Кэнту Delphi 7 для профессионалов
 
почитайте Марко Кэнту Delphi 7 для профессионалов
Ну так поведай нам, о профессионал, как же профессионалы имеют в рамках одного приложения два объекта Аппликейшн. А еще лучше семпл приложи - и мы сразу проникнемся твоей уличной магией.
 
ТС, поройся в свойствах этих ПейджКонтролов и ТабШитов, найди у кого-нить Draw(), Redraw() или чего-нить похожее и после создания СтрингГрид-а - дерни. То есть заставь парента принудительно перерисоваться, он соответственно раздаст WM_PAINT всем чилдренам. Вдруг поможет. От этих свиней VCL всего можно ожидать.
Вызывал вручную Redraw, Refresh - толку ровно ноль.
 
пример

library Project1;

uses
SysUtils,
Classes,
Unit1 in 'Unit1.pas' {Form1};

{$R *.res}
exports ShowAbout index 10;

begin
end.


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;

type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
procedure ShowAbout(Handle: THandle);export;stdcall;

implementation

{$R *.dfm}

procedure ShowAbout(Handle: THandle);
begin
//Установить указатель на приложение
Application.Handle := Handle;
//Создать форму
Form1:= TForm1.Create(Application);
//Отобразить
Form1.ShowModal;
//Очистить
Form1.Free;
end;

end.
 
так ведь мне не саму форму надо создать, а уже на готовой форме приложения разместить контролы из DLL.

Application->Handle = HostApplication->Handle ничего не дает.
Reapint тоже ничего не дает.
Вкладка отображается, все что на ней делаю из библиотеки - не отображается.
 
А почему бы тебе не выложить сюда код ДЛЛ-ки и главного приложения? А мы посмотрим.
 
это был только пример не касающийся данной задачи
можете прикрепить архив с исходником проекта и библиотеки?
попробуйте добавить
info->ResultGrid->Visible = true;
 
plugin.h
Код:
#ifndef PLUGIN_H
#define PLUGIN_H

#define __BUILDING_THE_DLL

#ifdef  __BUILDING_THE_DLL
#define __EXPORT_TYPE __export
#else
#define __EXPORT_TYPE __import
#endif

#include    <vcl.h>
#include    <ComCtrls.hpp>
#include    <Grids.hpp>

#include    "D:/Work/MMNTester/Logging.h"

typedef struct
{
    unsigned    long        signature;        
    unsigned    short       major_ver;
    unsigned    short       minor_ver;
    unsigned    long        flags;              
    char                    description[128];  
    __stdcall   void        (*start_test)(); 
    __stdcall   void        (*stop_test)();  
    __stdcall   void        (*init_test)();    
    __stdcall   bool        (*load_result)(const char * filename);
    __stdcall   bool        (*save_result)(const char * filename);
    __stdcall   void        (*show_settings)();
    __stdcall   void        (*refresh_result)();StringGrid

    HWND                    AppHandle;
    TForm           *       ParentForm;
    TPageControl    *       PageControl;
    TLogging        *       MainLog;
    TLogging        *       TestLog;

    TStringGrid     *       ResultGrid;
    TTabSheet       *       PluginSheet;
}
plugin_info_t;


void  __init_plugin(plugin_info_t * info);

typedef void    __EXPORT_TYPE   __stdcall   (*get_plugin_info_proc_t)(plugin_info_t * info);

extern "C"  void    __EXPORT_TYPE   __stdcall   get_plugin_info(plugin_info_t * info);
extern "C"  void    __EXPORT_TYPE   __stdcall   init_plugin(plugin_info_t * info);
extern "C"  void    __EXPORT_TYPE   __stdcall   free_plugin(plugin_info_t * info);

#endif

plugin.cpp
Код:
#include    <sysutils.hpp>
#include    <vcl.h>
#include    <Controls.hpp>
#include    <ComCtrls.hpp>
#include    <Grids.hpp>
#include    "plugin.h"

void   __EXPORT_TYPE    __stdcall   get_plugin_info(plugin_info_t * info)
{
    memset(info,0,sizeof(plugin_info_t));
    info->major_ver = 0;
    info->minor_ver = 1;
    strcpy(info->description,"plugin info");
}

void    __EXPORT_TYPE   __stdcall   init_plugin(plugin_info_t * info)
{
    Application->Handle = info->AppHandle;

    info->PluginSheet = new TTabSheet(info->PageControl);
    info->PluginSheet->ParentFont = false;
    info->PluginSheet->Caption = "Plugin";
    info->PluginSheet->Name = "Page4";
    info->PluginSheet->PageControl = info->PageControl;
    info->PluginSheet->Visible = true;
    info->PluginSheet->TabVisible = true;

    info->ResultGrid = new TStringGrid(info->PluginSheet);
    info->ResultGrid->ParentFont = false;
    info->ResultGrid->Name = "SG1";
    info->ResultGrid->Parent = info->PluginSheet;
    info->ResultGrid->Visible = true;

}

void    __EXPORT_TYPE   __stdcall   free_plugin(plugin_info_t * info)
{
    if(info->PluginSheet)
    {
        info->PluginSheet->Free();
    }
}

вот процедура в главном приложении которая вызывает dllку
Код:
if(plugin) //plugin - dll HInstance 
    {
        _get_info = (get_plugin_info_proc_t)GetProcAddress(plugin,"get_plugin_info");
        _init_plg = (get_plugin_info_proc_t)GetProcAddress(plugin,"init_plugin");
        _free_plg = (get_plugin_info_proc_t)GetProcAddress(plugin,"free_plugin");
        if(!_get_info || !_init_plg || !_free_plg)
        {
            MessageBox(this->Handle,"Plugin load error",MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
        }
        else
        {
            _get_info(&info);
            info.AppHandle = Application->Handle;            
            info.ParentForm = this;
            info.PageControl = this->PageControl1;
        }
     }


void __fastcall TMainForm::ToolButton8Click(TObject *Sender)
{
   _init_plg(&info); //тут вызываю создание вкладки в dll
}

На главной форме расположен PageControl указатель которого передаю в либу. Пердварительно уже на нем есть 4 вкладки, отсальные хочу добавлять по мере загрузки плагинов
 
пример
procedure ShowAbout(Handle: THandle);
begin
//Установить указатель на приложение
Application.Handle := Handle;
//Создать форму
Form1:= TForm1.Create(Application);
//Отобразить
Form1.ShowModal;
//Очистить
Form1.Free;
end;
Ты вообще понимаешь что пишешь? Ты получил в параметрах ху знает какой функции ху знает откуда ху знает какой хендл - и утверждаешь что это хендл отдельного объекта Аппликейшн, принадлежащего ДЛЛ-ке?!?!? Гениально. У тебя с головой все в порядке?

Кстати для тебя, гениального, еще один момент, который для тебя явно станет откровением: хендл и указатель - ДВЕ РАЗНЫЕ ВЕЩИ :D

plugin.h
.......
[/CODE]

На главной форме расположен PageControl указатель которого передаю в либу. Пердварительно уже на нем есть 4 вкладки, отсальные хочу добавлять по мере загрузки плагинов
А как бы тебе выложить сюда архивчик? ;) Всем стало бы удобнее...
 
вырезал всю логику и лишнее,
по нажатию на кнопку должна создаться вкладка из плагина
 
Останнє редагування:
пример взят из книги, на комментарий не обратил внимание.
ShowAbout вызывается из главного приложения, передается Application.Handle главного приложения.
пример проверялся и работал корректно.

P.S. переходить на личности и оскорблять это нехорошо
 
вырезал всю логику и лишнее,
по нажатию на кнопку должна создаться вкладка из плагина
Хмм. Сбили меня с паталыку эти дельфийные примеры - чет решил что у тебя тоже дельфя. Не стоит бюлдера - ни к чему он мне, виноват с просьбами архивов :(
Но число умозрительно в рамках "танца с бубном":
1. Попробуй LoadLibrary перенести из конструктора в FormCreate()
2. Если не поможет - попробуй все (включая ЛоадЛайбрери) из FormCreate в какое-нить FormShow()

пример взят из книги, на комментарий не обратил внимание.
ShowAbout вызывается из главного приложения, передается Application.Handle главного приложения.
пример проверялся и работал корректно.
Скажи ради всего святого, что тебя натолкнуло на мысль, что Application в точке вызова процедуры и Application внутри процедуры - это два разных объекта?!?!? :confused:
Неужели это было написано в книге?!?!?! :eek:
 
Application это один и тот же объект конечно. возможно не совсем удачно выразился
еще не мешало бы в бибилиотеке добавить обработку исключений
 
Application это один и тот же объект конечно. возможно не совсем удачно выразился
еще не мешало бы в бибилиотеке добавить обработку исключений

В библиотеке и приложении один и тот же экземпляр TApplication?
 
пока все методы что вы подсказали перепробовал - не работает. возможно глюк самого vcl. потому что все примеры что в инете нашел не дали никакого результата.
 
Назад
Зверху Знизу