经历过Windows 95以及之前版本的用户,都对Windows98之后的Windows可以支持多个显卡惊讶不已,其实从Windows98开始,Windows系统也可以支持多个桌面了,新的API提供了一组使用Desktop桌面和Workstaion工作站的函数: CloseDesktop CloseWindowStation CreateDesktop CreateWindowStation EnumDesktopProc EnumDesktops EnumDesktopWindows EnumWindowStationProc EnumWindowStations GetProcessWindowStation GetThreadDesktop GetUserObjectInformation GetUserObjectSecurity OpenDesktop OpenInputDesktop OpenWindowStation SetProcessWindowStation SetThreadDesktop SetUserObjectInformation SetUserObjectSecurity SwitchDesktop 这些函数通常使用到的机会并不是很多,而且并不是十分具有很好的实用价值,但是,如果如果希望你的程序实现一些特殊的用途,使用这组API则可以事半功倍,比如有很多系统像超市的Pos收银、记费等专业用途的程序,总是希望工作环境尽量的单一,甚至桌面没有开始菜单,各种图标,只有业务软件在运行,通常的做法是修改Windows的设置,将Shell给屏蔽掉,或者利用Windows“策略”来实现,这样作也会带来缺点,不使用业务软件的时候,计算机将没有任何用处。本文中的实例程序就可以很容易的实现这个功能,而不需要对系统作任何修订,当然使用的操作系统必须是Windows98以后的版本。 除了Desktop之外,Workstaion也是Windows98的一个新特征,Workstaion就是工作站,相当于在一个计算机上虚拟出别的工作站,至于他们的用途,用的好的话也许会很广泛,用的不好也许会宕机,我们后面的例子就是使用Workstation实现同时使用多个剪切板的功能。 首先我门来看一下Desktop和Workstation有什么特点。 Desktop在Windows的SDK这样描述: A desktop is a secure object contained within a window station object. A desktop has a logical display surface and contains windows, menus, and hooks. 这是一个逻辑上的层面,可以容纳其他的窗体、包括独立的Hooks和菜单(开始菜单、桌面快捷菜单等)。我们通常工作的桌面就是Desktop中的一个。 Workstation在Windows的SDK中这样描述: A window station is a secure object that contains a set of global atoms, a clipboard, and a set of desktop objects. 显然桌面是属于工作站的,这个没有违反客观规律,尽管一个系统中的桌面和工作站都是逻辑上的。工作站可以拥有独立的Atoms序列,剪切板,和桌面等。 上面这一组函数的使用方法,这里不想多说,帮助里面的更加正确和详细,稍微翻阅就可以搞定。 关于Desktop和Workstaion的应用自然限定在上述的范围之内,下面将给出两个简单的应用示范。 一个是Desktop的,这个程序通常情况下启动,没有什么特别的,当使用“/O”参数启动的时候,将会判断运行的桌面,如果程序不是运行在特定的桌面,就会返回,同时创建另一个运行在特定桌面的进程。这个特定的桌面不包括开始菜单,桌面的其他元素,是一个没有Shell的桌面。当程序结束的时候,如果是运行在特定桌面的将会关闭该桌面,也就是返回系统的缺省桌面。 主函数程序文件如下: #include <vcl.h> #pragma hdrstop USERES("Dsktp.res"); USEFORM("NewDsktp.cpp", Form3); USEUNIT("Ext.cpp"); //-------------------------------------------------------------------------- bool __fastcall CheckApp(TApplication* Application); bool __fastcall CloseDeskTop(); //-------------------------------------------------------------------------- WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR Param, int) { try { Application->Initialize(); if(AnsiString(Param).Pos("/O")) if(!CheckApp(Application)) { return 0; } Application->CreateForm(__classid(TForm3), &Form3); Application->Run(); if(AnsiString(Param).Pos("/O")) CloseDeskTop(); } catch (Exception &exception) { Application->ShowException(&exception); } return 0; } 这个程序中只有一个窗口单元和一个cpp单元Ext.cpp,其他的和一般程序没有很大的区别,只是增加了两个函数: bool __fastcall CheckApp(TApplication* Application);和 bool __fastcall CloseDeskTop(); CheckApp用于检测程序是否运行在特定的桌面,CloseDeskTop用于关闭特定的桌面,这两个函数都包含在Ext.cpp中,代码如下: #include <windows.h> #include <winnt.h> #include <vcl.h> HDESK DsktpHandle; char* MeDsktp = "MyDeskTop"; //特定的Desktop的名称 bool __fastcall CheckApp(TApplication* Application)//以当前的Application为参数 { bool Result; //函数返回的结果,true代表运行在正确的桌面 SECURITY_DESCRIPTOR sd; SECURITY_ATTRIBUTES sa; LPSECURITY_ATTRIBUTES lpsa = NULL; OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof(osv); GetVersionEx(&osv); if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT) //NT系统的话,需要指定lpsa参数 { InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&sd, true, NULL, false); sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; sa.lpSecurityDescriptor = &sd; lpsa = &sa; } STARTUPINFO si; memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES; si.wShowWindow = SW_SHOW; si.lpDesktop = MeDsktp; PROCESS_INFORMATION pi; //尝试打开特定的桌面 HDESK DsktpHandle = OpenDesktop(MeDsktp,DF_ALLOWOTHERACCOUNTHOOK, true,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if(!DsktpHandle) //打开失败则创建该桌面 { DsktpHandle = CreateDesktop(MeDsktp,NULL,NULL, DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS, lpsa); if(!DsktpHandle) { ShowMessage("DeskTop Creat Error!"); } Result = false; //特定桌面不存在,当前进程肯定没有运行在特定桌面 } else //特定的桌面存在,则判断当前的Application是否运行于该桌面 { STARTUPINFO SI; GetStartupInfo(&SI); //获取启动信息 if(AnsiString(SI.lpDesktop).Pos(MeDsktp)) //比较翕动的Desktop参数 { Result = true; //程序运行在正确(特定的’MyDeskTop’)的桌面 } else { Result = false; //程序没有运行在特定的桌面 } } if(Result == false && DsktpHandle) //特定的桌面存在,并且当前进程不在特定的桌面 { //则创建当前进程的一个新的运行副本,同时指定运行在特定的桌面 if( CreateProcess(NULL, Application->ExeName.c_str(), lpsa, lpsa, true, 0, 0, 0, &si, &pi)) { SwitchDesktop(DsktpHandle); //切换到特定的桌面,否则新的程序进程将看不到 } else { CloseDesktop(DsktpHandle); //进程创建失败,则关闭特定桌面 ShowMessage("rocess Creat Error!"); } } return Result; //WinMain根据返回值判断是否结束当前Application } bool __fastcall CloseDeskTop() { bool Result; //这个返回值没有使用。 HDESK DsktpHandle = OpenDesktop(MeDsktp,DF_ALLOWOTHERACCOUNTHOOK, true,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); Result = CloseDesktop(DsktpHandle); return Result; } 可以将这两个函数添加到任何的应用程序中,而且不需要改变其他代码,只需要在WinMain中按照上面的WinMain调用之,就可以实现程序运行到独立的Desktop桌面。 上面的代码中Form3可以是任意一个Form,都不会对Desktop产生影响,这个例子中Form3中使用了Workstation来实现同时使用多个剪切板。不过需要注意的是,在这个示范程序中,使用了其他Workstation的剪切板后,程序退出的时候,一定要将剪切板清空,否则大家试一下就知道了,呵呵… Form3的界面如下: 两个列表窗分别用来列表系统中的Workstation和某个Workstation中的Desktop。 右边的Label将会显示当前Application的一个Desktop和Workstation的信息。 中间的两个Edit和Button允许用户输入名称,并按照名称创建新的Desktop和Workstaion 其他的几个Button功能就在Button上写着 右下方的小窗口有8个带有数字的按钮,Form3创建后,会自动创建7个Workstation,和程序本身运行时的Workstation,公有8个Workstation可以共程序选择,点击数字按钮可以将程序切换到相应的Workstaion。 测试效果(仅给出测试剪切板): 在Edit1中输入1111,选中并复制,然后将Workstation切换到2,然后在Edit1中输入2222,全部选中并复制,然后切换到Workstation 3,在Edit2中粘贴,什么都没有粘贴上,切换回Workstation1,在Edit2中粘贴,结果是1111,切换到Workstation2中同样粘贴,结果是2222。 Form3的代码如下: #include <vcl.h> #pragma hdrstop #include "NewDsktp.h" #include <clipbrd.hpp> //-------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm3 *Form3; BOOL CALLBACK MyEnumDesktopProc(LPTSTR lpszDesktop,LPARAM lParam); //-------------------------------------------------------------------------- __fastcall TForm3::TForm3(TComponent* Owner) : TForm(Owner) { } //-------------------------------------------------------------------------- bool CALLBACK MyEnumDesktopProc(LPTSTR lpszDesktop,LPARAM lParam) { if(lParam == 0) Form3->ListBox1->Items->Add(lpszDesktop); else if(lParam == 1) Form3->ListBox2->Items->Add(lpszDesktop); return true; } void __fastcall TForm3::Button2Click(TObject *Sender) { // if(ListBox2->ItemIndex == -1) // { // ShowMessage("未选择WorkStation"); // return; // } ListBox1->Items->Clear(); EnumDesktops(GetProcessWindowStation(), (DESKTOPENUMPROC)MyEnumDesktopProc,0); } //-------------------------------------------------------------------------- void __fastcall TForm3::Button3Click(TObject *Sender) { ListBox2->Items->Clear(); EnumWindowStations((WINSTAENUMPROC)MyEnumDesktopProc,1); } //-------------------------------------------------------------------------- void __fastcall TForm3:istBox2Click(TObject *Sender) { if(ListBox2->ItemIndex == -1) { ShowMessage("未选择WorkStation"); return; } ListBox1->Items->Clear(); HWINSTA Wkst; Wkst = OpenWindowStation(ListBox2->Items->Strings[ListBox2->ItemIndex]. c_str(), true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); EnumDesktops(Wkst,(DESKTOPENUMPROC)MyEnumDesktopProc,0); } //-------------------------------------------------------------------------- void __fastcall TForm3::Button4Click(TObject *Sender) { if(ListBox2->ItemIndex == -1) { ShowMessage("请选择一个Desktop"); return; } HDESK DsktpHandle = OpenDesktop(ListBox1->Items-> Strings[ListBox1->ItemIndex].c_str(), DF_ALLOWOTHERACCOUNTHOOK,true, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if(!DsktpHandle) { ShowMessage("Open Desktop Error!"); } else { SwitchDesktop(DsktpHandle); } } //-------------------------------------------------------------------------- void __fastcall TForm3::Button5Click(TObject *Sender) { AnsiString WkstName = Edit1->Text; Button3Click(Sender); if( ListBox2->Items->IndexOf(WkstName) != -1) { ShowMessage("这个Work Station已经存在了!"); } else { HWINSTA hWkst = CreateWindowStation(WkstName.c_str(),NULL, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES,NULL); if(!hWkst) { ShowMessage("Create Wkst Error!"); } else { ListBox2->Items->Clear(); EnumWindowStations((WINSTAENUMPROC)MyEnumDesktopProc,1); } } } //-------------------------------------------------------------------------- void __fastcall TForm3::Button6Click(TObject *Sender) { AnsiString DsktpName = Edit2->Text; Button2Click(Sender); if( ListBox1->Items->IndexOf(DsktpName) != -1) { ShowMessage("这个DeskTop已经存在了!"); } HDESK DsktpHandle = CreateDesktop(DsktpName.c_str(),NULL,NULL, DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS, NULL); if(!DsktpHandle) { ShowMessage("DeskTop Creat Error!"); } } //-------------------------------------------------------------------------- void __fastcall TForm3::Button7Click(TObject *Sender) { if(ListBox2->ItemIndex == -1) { ShowMessage("请选择一个Desktop"); return; } HDESK DsktpHandle = OpenDesktop(ListBox1->Items-> Strings[ListBox1->ItemIndex].c_str(), DF_ALLOWOTHERACCOUNTHOOK,true, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if(!DsktpHandle) { ShowMessage("Open Desktop Error!"); } else { CloseDesktop(DsktpHandle); } } //--------------------------------------------------------------------------- void __fastcall TForm3::Button1Click(TObject *Sender) { HWINSTA Wkst; if(ListBox2->ItemIndex == -1) { ShowMessage("未选择WorkStation"); return; } Wkst = OpenWindowStation(ListBox2->Items-> Strings[ListBox2->ItemIndex].c_str(), true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); if(Wkst) { bool Res = SetProcessWindowStation(Wkst); if(!Res) ShowMessage("Set Wkst Error!"); } } //-------------------------------------------------------------------------- void __fastcall TForm3::Button8Click(TObject *Sender) { USEROBJECTFLAGS OS; char Info[256]; unsigned long ActualLength; HANDLE hHandle = GetProcessWindowStation(); if( hHandle && GetUserObjectInformation(hHandle, UOI_NAME,Info,256,&ActualLength)) { Label6->Caption = Info; } else { Label6->Caption = "Get Info Error!"; } hHandle = GetThreadDesktop(GetCurrentThreadId()); if( hHandle && GetUserObjectInformation(hHandle, UOI_NAME,Info,256,&ActualLength)) { Label8->Caption = Info; } else { Label8->Caption = "Get Info Error!"; } hHandle = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK,true, DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS); if( hHandle && GetUserObjectInformation(hHandle, UOI_NAME,Info,256,&ActualLength)) { Label10->Caption = Info; } else { Label10->Caption = "Get Info Error!"; } STARTUPINFO SI; GetStartupInfo(&SI); Label12->Caption = AnsiString(SI.lpDesktop); } //-------------------------------------------------------------------------- void __fastcall TForm3::FormCreate(TObject *Sender) { HANDLE hTemp; hTemp = GetProcessWindowStation(); USEROBJECTFLAGS OS; char Info[256]; unsigned long ActualLength; HANDLE hHandle = GetProcessWindowStation(); if( hHandle && GetUserObjectInformation(hTemp,UOI_NAME,Info,256,&ActualLength)) { PrivateWkst[0] = Info; } AnsiString Name = "Station"; for(int i = 1; i < 8; i++) { PrivateWkst[i] = Name + IntToStr(i); hTemp = CreateWindowStation(PrivateWkst[i].c_str(),NULL, WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES,NULL); } } //-------------------------------------------------------------------------- void __fastcall TForm3::ToolButton1Click(TObject *Sender) { int Index = ((TToolButton*)Sender)->Tag; HANDLE Wkst = OpenWindowStation(PrivateWkst[Index].c_str(), true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES); if(Wkst) { bool Res = SetProcessWindowStation(Wkst); if(!Res) { ShowMessage("Set Wkst Error!"); } Button8Click(Sender); } Button8Click(Sender); } //-------------------------------------------------------------------------- void __fastcall TForm3::Button9Click(TObject *Sender) { Clipboard()->Clear(); } //-------------------------------------------------------------------------- 头文件如下: #ifndef NewDsktpH #define NewDsktpH //-------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ExtCtrls.hpp> #include <ComCtrls.hpp> #include <ToolWin.hpp> //-------------------------------------------------------------------------- class TForm3 : public TForm { __published: TListBox *ListBox1; TListBox *ListBox2; TLabel *Label1; TLabel *Label2; TButton *Button2; TButton *Button3; TButton *Button4; TPanel *Panel1; TEdit *Edit1; TEdit *Edit2; TButton *Button5; TButton *Button6; TLabel *Label3; TLabel *Label4; TButton *Button7; TButton *Button1; TLabel *Label5; TLabel *Label6; TLabel *Label7; TLabel *Label8; TLabel *Label9; TLabel *Label10; TLabel *Label11; TLabel *Label12; TButton *Button8; TPanel *Panel2; TToolBar *ToolBar1; TToolButton *ToolButton1; TToolButton *ToolButton2; TToolButton *ToolButton3; TToolButton *ToolButton4; TToolButton *ToolButton5; TToolButton *ToolButton6; TToolButton *ToolButton7; TToolButton *ToolButton8; TLabel *Label13; TButton *Button9; void __fastcall Button2Click(TObject *Sender); void __fastcall Button3Click(TObject *Sender); void __fastcall ListBox2Click(TObject *Sender); void __fastcall Button4Click(TObject *Sender); void __fastcall Button5Click(TObject *Sender); void __fastcall Button6Click(TObject *Sender); void __fastcall Button7Click(TObject *Sender); void __fastcall Button1Click(TObject *Sender); void __fastcall Button8Click(TObject *Sender); void __fastcall FormCreate(TObject *Sender); void __fastcall ToolButton1Click(TObject *Sender); void __fastcall Button9Click(TObject *Sender); private: public: AnsiString PrivateWkst[8]; __fastcall TForm3(TComponent* Owner); }; //-------------------------------------------------------------------------- extern PACKAGE TForm3 *Form3; //-------------------------------------------------------------------------- #endif Dfm文件如下: object Form3: TForm3 Left = 325 Top = 115 BorderIcons = [biSystemMenu] BorderStyle = bsSingle Caption = 'Run On New DeskTop'#39's Form' ClientHeight = 366 ClientWidth = 622 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False OnCreate = FormCreate PixelsPerInch = 96 TextHeight = 13 object Label1: TLabel Left = 208 Top = 8 Width = 66 Height = 12 Caption = 'Desktop列表' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label2: TLabel Left = 16 Top = 8 Width = 90 Height = 12 Caption = 'Workstation列表' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label5: TLabel Left = 400 Top = 24 Width = 120 Height = 12 Caption = '当前进程的WokStation' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label6: TLabel Left = 400 Top = 48 Width = 6 Height = 12 Caption = ' ' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label7: TLabel Left = 400 Top = 72 Width = 90 Height = 12 Caption = '当前线程Desktop' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label8: TLabel Left = 400 Top = 96 Width = 6 Height = 12 Caption = ' ' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label9: TLabel Left = 400 Top = 120 Width = 108 Height = 12 Caption = '当前Input的DeskTop' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label10: TLabel Left = 400 Top = 144 Width = 6 Height = 12 Caption = ' ' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label11: TLabel Left = 400 Top = 168 Width = 102 Height = 12 Caption = '程序的启动DeskTop' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label12: TLabel Left = 400 Top = 192 Width = 6 Height = 12 Caption = ' ' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label13: TLabel Left = 520 Top = 240 Width = 90 Height = 12 Caption = '切换WorkStation' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object ListBox1: TListBox Left = 208 Top = 24 Width = 177 Height = 161 ItemHeight = 13 TabOrder = 0 end object ListBox2: TListBox Left = 16 Top = 24 Width = 177 Height = 161 ItemHeight = 13 TabOrder = 1 OnClick = ListBox2Click end object Button2: TButton Left = 16 Top = 320 Width = 75 Height = 25 Caption = '枚举DskTp' TabOrder = 2 OnClick = Button2Click end object Button3: TButton Left = 112 Top = 320 Width = 75 Height = 25 Caption = '枚举Wkst' TabOrder = 3 OnClick = Button3Click end object Button4: TButton Left = 208 Top = 320 Width = 75 Height = 25 Caption = '切换DskTp' TabOrder = 4 OnClick = Button4Click end object Panel1: TPanel Left = 16 Top = 192 Width = 369 Height = 113 BevelInner = bvSpace BevelOuter = bvLowered TabOrder = 5 object Label3: TLabel Left = 16 Top = 80 Width = 78 Height = 12 Caption = 'Desktop名称:' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Label4: TLabel Left = 16 Top = 32 Width = 102 Height = 12 Caption = 'Workstation名称:' Font.Charset = GB2312_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = '宋体' Font.Style = [] ParentFont = False end object Edit1: TEdit Left = 120 Top = 24 Width = 121 Height = 21 TabOrder = 0 end object Edit2: TEdit Left = 120 Top = 72 Width = 121 Height = 21 TabOrder = 1 end object Button5: TButton Left = 272 Top = 21 Width = 75 Height = 25 Caption = '创建Wkst' TabOrder = 2 OnClick = Button5Click end object Button6: TButton Left = 272 Top = 69 Width = 75 Height = 25 Caption = '创建Dsktp' TabOrder = 3 OnClick = Button6Click end end object Button7: TButton Left = 304 Top = 320 Width = 75 Height = 25 Caption = '关闭Dsktp' TabOrder = 6 OnClick = Button7Click end object Button1: TButton Left = 408 Top = 280 Width = 75 Height = 25 Caption = '切换Wkst' Enabled = False TabOrder = 7 OnClick = Button1Click end object Button8: TButton Left = 408 Top = 240 Width = 75 Height = 25 Caption = '获取信息' TabOrder = 8 OnClick = Button8Click end object Panel2: TPanel Left = 520 Top = 271 Width = 77 Height = 51 BevelInner = bvSpace BevelOuter = bvLowered TabOrder = 9 object ToolBar1: TToolBar Left = 2 Top = 2 Width = 73 Height = 47 Align = alNone ButtonHeight = 23 ButtonWidth = 14 Caption = 'ToolBar1' EdgeBorders = [] Flat = True Font.Charset = ANSI_CHARSET Font.Color = clWindowText Font.Height = -12 Font.Name = 'Courier New' Font.Style = [] ParentFont = False ShowCaptions = True TabOrder = 0 object ToolButton1: TToolButton Left = 0 Top = 0 AutoSize = True Caption = '1' Down = True Grouped = True ImageIndex = 0 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton2: TToolButton Tag = 1 Left = 18 Top = 0 AutoSize = True Caption = '2' Grouped = True ImageIndex = 1 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton3: TToolButton Tag = 2 Left = 36 Top = 0 AutoSize = True Caption = '3' Grouped = True ImageIndex = 2 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton4: TToolButton Tag = 3 Left = 54 Top = 0 AutoSize = True Caption = '4' Grouped = True ImageIndex = 3 Wrap = True Style = tbsCheck OnClick = ToolButton1Click end object ToolButton5: TToolButton Tag = 4 Left = 0 Top = 23 AutoSize = True Caption = '5' Grouped = True ImageIndex = 4 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton6: TToolButton Tag = 5 Left = 18 Top = 23 AutoSize = True Caption = '6' Grouped = True ImageIndex = 5 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton7: TToolButton Tag = 6 Left = 36 Top = 23 AutoSize = True Caption = '7' Grouped = True ImageIndex = 6 Style = tbsCheck OnClick = ToolButton1Click end object ToolButton8: TToolButton Tag = 7 Left = 54 Top = 23 AutoSize = True Caption = '8' Grouped = True ImageIndex = 7 Style = tbsCheck OnClick = ToolButton1Click end end end object Button9: TButton Left = 408 Top = 320 Width = 75 Height = 25 Caption = '清空剪切板' TabOrder = 10 OnClick = Button9Click end end