新建一个delphi6.0工程时,会自动创建一个form1.dfm作为资源文件,里面是一些初始信息,但实际上这些信息都不重要,完全可以在create事件中修改,所有的控件也可以在create事件中创建,并且可以写变量、数组等,在控件比较多且有规律时比较有效,但如果将.pas文件中的{$R *.dfm}注释上系统会提示资源未找到,如何将其彻底去掉?如果我在工程文件里直接写
program Project1;
uses
  Forms;
var
  Form1:TForm;
begin
  Application.Initialize;
  Application.CreateForm(TForm, Form1);
  Form1.top:=100;
  Application.Run;
end.
同样可以弹出默认窗口(仅此一个.dpr文件就可以编译,会自动创建.res文件),同样可以继续添加控件,以及为属性、事件赋值,与一般窗口无异,但没有TForm1类,在窗口较多时会比较麻烦(所有的函数、事件都写在一起),我希望工程中是一个.dpr文件和若干个.pas文件,作为资源文件中存储的都应该是直接看不懂的东东,如图片、声音等,而不应该有.dfm中那些直接能读懂的。总的来说,就是想在程序中动态创建所有窗口,创建过程不需要资源文件支持。该怎么做?请指教。

解决方案 »

  1.   

    新建一个Console程序,然后按如下书写:program Project1;//{$APPTYPE CONSOLE}  //把这句注释掉uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,stdCtrls;
    var
      form1:TForm;
      button:TButton;
    begin
      { TODO -oUser -cConsole Main : Insert code here }
      application.Initialize;
      application.CreateForm(TForm,form1);
      button:=TButton.Create(form1);
      button.Caption:='asdfasdfasdf';
      button.Width:=160;
      button.Parent:=form1;
      application.Run;
    end.
      

  2.   

    更简单的,窗口一闪而过:program Project1;//{$APPTYPE CONSOLE}  //把这句注释掉uses
      Forms;
    var
      form1:TForm;
    begin
      form1:=TForm.Create(nil);
      form1.Show;  
    end.
      

  3.   

    thanks to all.
    但好像跟我上面写的思路差不多,我可以将所有程序写到.dpr文件中,这样会很乱,所以我依然希望有TForm1这个类,并且将绝大部分与TForm1相关的程序都写到一个比如叫Form1.pas的文件中,这样程序的结构化会好一些。
      

  4.   

    如果你不想加入.DFM的话,你可以在最初时创建一个UNIT,File->New->Unit
      

  5.   

    to idilent:
    我并不觉得很累,尤其是控件多且有规律的时候,比如整齐排列100个按钮(10*10),用数组会方便很多,另外我觉得还能减少垃圾。to Wally_wu:
    新建一个unit的结果是一样的,例如在unit1中写
    type
      TForm1 = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;在dpr文件中的
    Application.CreateForm(TForm1, Form1);
    依然会报错说资源找不到,就是因为没有unit1.dfm。
      

  6.   

    是不是用Application.CreateForm创建的必须要有资源,还是说TForm1声明的时候就必须有资源?
      

  7.   

    如果你连主窗口都想动态创建,那你还不如自己注册一个窗口类呢,那样的话,就只有一个dpr和若干pas了,不过消息循环可比较麻烦,但程序很小哦
      

  8.   

    能具体一点吗?该怎么做?你的意思是不是TForm1不从TForm类继承,而是全新创建的?那程序中该写什么呢?
      

  9.   

    program small;uses
      windows,
      messages;
      //sysutils;{$R *.RES}
    var winclass:twndclass;
    handle,button1:integer;
    msg:tmsg;
    function WindowProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;
    begin
      Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
      { Checks for messages }
      if (lParam = button1) and (uMsg = WM_COMMAND) then
        SetWindowText(handle,'windows');
      if uMsg = WM_DESTROY then
        Halt;
    end;
    procedure m;
    begin
        winclass.style:=0;
        winclass.lpfnWndProc:=@WindowProc;
        winclass.hInstance:=system.MainInstance;
        winclass.hCursor:=0;
        winclass.hbrBackground:=color_btnface + 1;
        winclass.lpszClassName:='textclass';
        registerclass(winclass);
        //Handle := CreateWindowEx(WS_EX_WINDOWEDGE, 'textclass', 'text',
        //                       WS_VISIBLE or WS_SIZEBOX or WS_CAPTION or WS_SYSMENU,
        //                       363, 278, 305, 65, 0, 0, hinstance, nil);
        handle:=windows.CreateWindow('textclass','text',ws_caption or ws_visible or WS_SYSMENU
        ,200,200,300,300,0,0,hinstance,nil);
        button1:=CreateWindow('button', 'ok', WS_VISIBLE or WS_CHILD or BS_text or BS_PUSHLIKE,
                               20, 20, 30, 20, handle, 0, hinstance, nil);
        UpdateWindow(Handle);
    end;begin
        m;    //ShowWindow(handle,SW_HIDE);
        while (GetMessage(Msg,handle, 0, 0)) do
      begin
        TranslateMessage(msg);
        DispatchMessage(msg);
        UpdateWindow(Handle);
      end;
    end.
    以上就是一个dpr文件,编译后10k
      

  10.   

    非常感谢,的确很好,文件也小,delphi的默认工程编译后又351k大,但这是从c抄过来的吧,一点delphi的风格都没有了,而且需要把{$R *.RES}注释上,否则同样会提示找不到资源文件。另:delphi的常规手法都用不上了,这样当窗口、控件多起来后程序会不会很乱?
      

  11.   

    是不是要脱离vcl,我有办法,等我找一下,先帮你up
      

  12.   

    建一工程,把单元unit1去除,将工程保存为testwindow.dpr,在delphi的ide下,将如下代码完全替换掉delphi里自动生成的代码,编译,将收到一个8k的应用程序,你看一下。呵
    program testwindow;uses
      Windows, Messages;var
      WinClass: TWndClassA;
      Inst, Handle: Integer;
      Msg: TMsg;begin
      Inst := hInstance;
      with WinClass do
      begin
        style              := CS_CLASSDC or CS_PARENTDC;
        lpfnWndProc        := @DefWindowProc;
        hInstance          := Inst;
        hbrBackground      := color_btnface + 1;
        lpszClassname      := 'AG_TESTWINDOW';
        hCursor            := LoadCursor(0, IDC_ARROW);
      end; { with }
      RegisterClass(WinClass);  { ** Create Main Window ** }
      Handle := CreateWindowEx(WS_EX_WINDOWEDGE, 'AG_TESTWINDOW', 'Amigreen TestWindow 1.00',WS_VISIBLE or WS_SIZEBOX or WS_CAPTION or WS_SYSMENU, 363, 278, 305, 65, 0, 0, Inst, nil);
      UpdateWindow(Handle);  { ** Message Loop ** }
      while(GetMessage(Msg, Handle, 0, 0)) do
      begin
        TranslateMessage(msg);
        DispatchMessage(msg);
      end; { with }
    end.
      

  13.   

    非常感谢,我更希望在不改变delphi风格的情况下,去掉dfm文件,如果放弃delphi的风格,感觉得不偿失,毕竟我对c不是特熟,否则就直接用c了,可能是这个希望太苛刻了。
    创建窗口:
    Application.CreateForm(TForm1, Form1);
    此语句不需dfm文件,且form1的其他相关程序放在form1.pas中,包括TForm1的定义。
    创建按钮:
    b:=TButton.Create(self);
    b.Parent:=self;
    b.Caption:="OK";
    b.OnClick:=ClickThisButton;
    其中PushThisButton是form1的函数
    procedure TForm1.ClickThisButton(Sender: TObject);
    可能是这样写习惯了,也没觉得什么不好(除了dfm)。
      

  14.   

    提这个问题还有另外一个原因,就是在论坛上提问时,别人会很热心的将他们的源程序贴出来,但一般贴出的都是整个.pas文件,如果没有.dfm文件,想让这个.pas文件运行是很麻烦的,必须从.pas文件中找出所有用到的控件,手动添加控件及事件,再将程序中的函数段(不能包括函数定义等)一点一点的copy过去,如果控件很多的话就极为繁琐,如果能不需要.dfm文件就可以编译运行并立刻看到结果,对学习是有帮助的。