DeskTop与WorkStation使用两则

[cpp]  view plain copy
  1.   经历过Windows 95以及之前版本的用户,都对Windows98之后的Windows可以支持多个显卡惊讶不已,其实从Windows98开始,Windows系统也可以支持多个桌面了,新的API提供了一组使用Desktop桌面和Workstaion工作站的函数:  
  2.   
  3. CloseDesktop  
  4. CloseWindowStation  
  5. CreateDesktop  
  6. CreateWindowStation  
  7. EnumDesktopProc  
  8. EnumDesktops  
  9. EnumDesktopWindows  
  10. EnumWindowStationProc  
  11. EnumWindowStations  
  12. GetProcessWindowStation  
  13. GetThreadDesktop  
  14. GetUserObjectInformation  
  15. GetUserObjectSecurity  
  16. OpenDesktop  
  17. OpenInputDesktop  
  18. OpenWindowStation  
  19. SetProcessWindowStation  
  20. SetThreadDesktop  
  21. SetUserObjectInformation  
  22. SetUserObjectSecurity  
  23. SwitchDesktop  
  24.   
  25.   这些函数通常使用到的机会并不是很多,而且并不是十分具有很好的实用价值,但是,如果如果希望你的程序实现一些特殊的用途,使用这组API则可以事半功倍,比如有很多系统像超市的Pos收银、记费等专业用途的程序,总是希望工作环境尽量的单一,甚至桌面没有开始菜单,各种图标,只有业务软件在运行,通常的做法是修改Windows的设置,将Shell给屏蔽掉,或者利用Windows“策略”来实现,这样作也会带来缺点,不使用业务软件的时候,计算机将没有任何用处。本文中的实例程序就可以很容易的实现这个功能,而不需要对系统作任何修订,当然使用的操作系统必须是Windows98以后的版本。  
  26.   
  27.   除了Desktop之外,Workstaion也是Windows98的一个新特征,Workstaion就是工作站,相当于在一个计算机上虚拟出别的工作站,至于他们的用途,用的好的话也许会很广泛,用的不好也许会宕机,我们后面的例子就是使用Workstation实现同时使用多个剪切板的功能。  
  28.   
  29.   首先我门来看一下Desktop和Workstation有什么特点。  
  30.   
  31.   Desktop在Windows的SDK这样描述:  
  32.   
  33. 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.  
  34.   
  35.   这是一个逻辑上的层面,可以容纳其他的窗体、包括独立的Hooks和菜单(开始菜单、桌面快捷菜单等)。我们通常工作的桌面就是Desktop中的一个。  
  36.   
  37.   Workstation在Windows的SDK中这样描述:  
  38.   
  39. A window station is a secure object that contains a set of global atoms, a clipboard, and a set of desktop objects.  
  40.   
  41.   显然桌面是属于工作站的,这个没有违反客观规律,尽管一个系统中的桌面和工作站都是逻辑上的。工作站可以拥有独立的Atoms序列,剪切板,和桌面等。  
  42.   
  43.   上面这一组函数的使用方法,这里不想多说,帮助里面的更加正确和详细,稍微翻阅就可以搞定。  
  44.   
  45.   关于Desktop和Workstaion的应用自然限定在上述的范围之内,下面将给出两个简单的应用示范。  
  46.   
  47.   一个是Desktop的,这个程序通常情况下启动,没有什么特别的,当使用“/O”参数启动的时候,将会判断运行的桌面,如果程序不是运行在特定的桌面,就会返回,同时创建另一个运行在特定桌面的进程。这个特定的桌面不包括开始菜单,桌面的其他元素,是一个没有Shell的桌面。当程序结束的时候,如果是运行在特定桌面的将会关闭该桌面,也就是返回系统的缺省桌面。  
  48.   
  49.   主函数程序文件如下:  
  50.   
  51. #include <vcl.h>  
  52. #pragma hdrstop  
  53. USERES("Dsktp.res");  
  54. USEFORM("NewDsktp.cpp", Form3);  
  55. USEUNIT("Ext.cpp");  
  56. //--------------------------------------------------------------------------  
  57. bool __fastcall CheckApp(TApplication* Application);  
  58. bool __fastcall CloseDeskTop();  
  59. //--------------------------------------------------------------------------  
  60. WINAPI WinMain(HINSTANCEHINSTANCELPSTR Param, int)  
  61. {  
  62.     try  
  63.     {  
  64.        Application->Initialize();  
  65.        if(AnsiString(Param).Pos("/O"))  
  66.          if(!CheckApp(Application))  
  67.          {  
  68.            return 0;  
  69.          }  
  70.        Application->CreateForm(__classid(TForm3), &Form3);  
  71.        Application->Run();  
  72.        if(AnsiString(Param).Pos("/O"))  
  73.          CloseDeskTop();  
  74.     }  
  75.     catch (Exception &exception)  
  76.     {  
  77.        Application->ShowException(&exception);  
  78.     }  
  79.     return 0;  
  80. }  
  81.   
  82.   这个程序中只有一个窗口单元和一个cpp单元Ext.cpp,其他的和一般程序没有很大的区别,只是增加了两个函数:  
  83.   
  84. bool __fastcall CheckApp(TApplication* Application);和  
  85. bool __fastcall CloseDeskTop();  
  86.   
  87.   CheckApp用于检测程序是否运行在特定的桌面,CloseDeskTop用于关闭特定的桌面,这两个函数都包含在Ext.cpp中,代码如下:  
  88.   
  89. #include <windows.h>  
  90. #include <winnt.h>  
  91. #include <vcl.h>  
  92. HDESK DsktpHandle;  
  93. char* MeDsktp = "MyDeskTop";      //特定的Desktop的名称  
  94. bool __fastcall CheckApp(TApplication* Application)//以当前的Application为参数  
  95. {  
  96.     bool Result;     //函数返回的结果,true代表运行在正确的桌面  
  97.     SECURITY_DESCRIPTOR sd;  
  98.     SECURITY_ATTRIBUTES sa;  
  99.     LPSECURITY_ATTRIBUTES lpsa = NULL;  
  100.     OSVERSIONINFO osv;  
  101.     osv.dwOSVersionInfoSize = sizeof(osv);  
  102.     GetVersionEx(&osv);  
  103.     if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT)  //NT系统的话,需要指定lpsa参数  
  104.     {  
  105.        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);  
  106.        SetSecurityDescriptorDacl(&sd, true, NULL, false);  
  107.        sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
  108.        sa.bInheritHandle = true;  
  109.        sa.lpSecurityDescriptor = &sd;  
  110.        lpsa = &sa;  
  111.     }  
  112.     STARTUPINFO si;  
  113.     memset(&si, 0, sizeof(STARTUPINFO));  
  114.     si.cb = sizeof(STARTUPINFO);  
  115.     si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;  
  116.     si.wShowWindow = SW_SHOW;  
  117.     si.lpDesktop = MeDsktp;  
  118.     PROCESS_INFORMATION pi;  //尝试打开特定的桌面  
  119.     HDESK DsktpHandle = OpenDesktop(MeDsktp,DF_ALLOWOTHERACCOUNTHOOK,  
  120.                         true,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  121.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  122.                         DESKTOP_JOURNALPLAYBACK |  
  123.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  124.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);  
  125.     if(!DsktpHandle)   //打开失败则创建该桌面  
  126.     {  
  127.        DsktpHandle = CreateDesktop(MeDsktp,NULL,NULL,  
  128.                         DF_ALLOWOTHERACCOUNTHOOK,  
  129.                         DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  130.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  131.                         DESKTOP_JOURNALPLAYBACK |  
  132.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  133.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS,  
  134.                         lpsa);  
  135.        if(!DsktpHandle)  
  136.        {  
  137.           ShowMessage("DeskTop Creat Error!");  
  138.        }  
  139.        Result = false;    //特定桌面不存在,当前进程肯定没有运行在特定桌面  
  140.     }  
  141.     else       //特定的桌面存在,则判断当前的Application是否运行于该桌面  
  142.     {  
  143.        STARTUPINFO SI;  
  144.        GetStartupInfo(&SI);    //获取启动信息  
  145.        if(AnsiString(SI.lpDesktop).Pos(MeDsktp))   //比较翕动的Desktop参数  
  146.        {  
  147.           Result = true;         //程序运行在正确(特定的’MyDeskTop’)的桌面  
  148.        }  
  149.        else  
  150.        {  
  151.           Result = false;        //程序没有运行在特定的桌面  
  152.        }  
  153.     }  
  154.     if(Result == false && DsktpHandle)   //特定的桌面存在,并且当前进程不在特定的桌面  
  155.     {             //则创建当前进程的一个新的运行副本,同时指定运行在特定的桌面  
  156.        if( CreateProcess(NULL, Application->ExeName.c_str(),  
  157.                           lpsa, lpsa, true, 0, 0, 0, &si, &pi))  
  158.        {  
  159.           SwitchDesktop(DsktpHandle);    //切换到特定的桌面,否则新的程序进程将看不到  
  160.        }  
  161.        else  
  162.        {  
  163.           CloseDesktop(DsktpHandle);    //进程创建失败,则关闭特定桌面  
  164.           ShowMessage("rocess Creat Error!");  
  165.        }  
  166.     }  
  167.     return Result;      //WinMain根据返回值判断是否结束当前Application  
  168. }  
  169. bool __fastcall CloseDeskTop()  
  170. {  
  171.     bool Result;    //这个返回值没有使用。  
  172.     HDESK DsktpHandle = OpenDesktop(MeDsktp,DF_ALLOWOTHERACCOUNTHOOK,  
  173.                         true,DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  174.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  175.                         DESKTOP_JOURNALPLAYBACK |  
  176.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  177.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);  
  178.     Result = CloseDesktop(DsktpHandle);  
  179.     return Result;  
  180. }  
  181.   
  182.   可以将这两个函数添加到任何的应用程序中,而且不需要改变其他代码,只需要在WinMain中按照上面的WinMain调用之,就可以实现程序运行到独立的Desktop桌面。  
  183.   
  184.   上面的代码中Form3可以是任意一个Form,都不会对Desktop产生影响,这个例子中Form3中使用了Workstation来实现同时使用多个剪切板。不过需要注意的是,在这个示范程序中,使用了其他Workstation的剪切板后,程序退出的时候,一定要将剪切板清空,否则大家试一下就知道了,呵呵…  
  185.   
  186.   Form3的界面如下:  
  187.   
  188.   两个列表窗分别用来列表系统中的Workstation和某个Workstation中的Desktop。  
  189.   
  190.   右边的Label将会显示当前Application的一个Desktop和Workstation的信息。  
  191.   
  192.   中间的两个Edit和Button允许用户输入名称,并按照名称创建新的Desktop和Workstaion  
  193.   
  194.   其他的几个Button功能就在Button上写着  
  195.   
  196.   右下方的小窗口有8个带有数字的按钮,Form3创建后,会自动创建7个Workstation,和程序本身运行时的Workstation,公有8个Workstation可以共程序选择,点击数字按钮可以将程序切换到相应的Workstaion。  
  197.   
  198.   测试效果(仅给出测试剪切板):  
  199.   
  200.   在Edit1中输入1111,选中并复制,然后将Workstation切换到2,然后在Edit1中输入2222,全部选中并复制,然后切换到Workstation 3,在Edit2中粘贴,什么都没有粘贴上,切换回Workstation1,在Edit2中粘贴,结果是1111,切换到Workstation2中同样粘贴,结果是2222。  
  201.   
  202.   Form3的代码如下:  
  203.   
  204. #include <vcl.h>  
  205. #pragma hdrstop  
  206. #include "NewDsktp.h"  
  207. #include <clipbrd.hpp>  
  208. //--------------------------------------------------------------------------  
  209. #pragma package(smart_init)  
  210. #pragma resource "*.dfm"  
  211. TForm3 *Form3;  
  212. BOOL CALLBACK MyEnumDesktopProc(LPTSTR lpszDesktop,LPARAM lParam);  
  213. //--------------------------------------------------------------------------  
  214. __fastcall TForm3::TForm3(TComponent* Owner)  
  215.     : TForm(Owner)  
  216. {  
  217. }  
  218. //--------------------------------------------------------------------------  
  219. bool CALLBACK MyEnumDesktopProc(LPTSTR lpszDesktop,LPARAM lParam)  
  220. {  
  221.     if(lParam == 0)  
  222.        Form3->ListBox1->Items->Add(lpszDesktop);  
  223.     else if(lParam == 1)  
  224.        Form3->ListBox2->Items->Add(lpszDesktop);  
  225.     return true;  
  226. }  
  227. void __fastcall TForm3::Button2Click(TObject *Sender)  
  228. {  
  229. //    if(ListBox2->ItemIndex == -1)  
  230. //    {  
  231. //       ShowMessage("未选择WorkStation");  
  232. //       return;  
  233. //    }  
  234.     ListBox1->Items->Clear();  
  235.     EnumDesktops(GetProcessWindowStation(),  
  236.                 (DESKTOPENUMPROC)MyEnumDesktopProc,0);  
  237. }  
  238. //--------------------------------------------------------------------------  
  239. void __fastcall TForm3::Button3Click(TObject *Sender)  
  240. {  
  241.     ListBox2->Items->Clear();  
  242.     EnumWindowStations((WINSTAENUMPROC)MyEnumDesktopProc,1);  
  243. }  
  244. //--------------------------------------------------------------------------  
  245. void __fastcall TForm3:istBox2Click(TObject *Sender)  
  246. {  
  247.     if(ListBox2->ItemIndex == -1)  
  248.     {  
  249.        ShowMessage("未选择WorkStation");  
  250.        return;  
  251.     }  
  252.     ListBox1->Items->Clear();  
  253.     HWINSTA Wkst;  
  254. Wkst = OpenWindowStation(ListBox2->Items->Strings[ListBox2->ItemIndex].  
  255.            c_str(),  
  256.            true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |  
  257.            WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |  
  258.            WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |  
  259.            WINSTA_READATTRIBUTES | WINSTA_READSCREEN |  
  260.            WINSTA_WRITEATTRIBUTES);  
  261.     EnumDesktops(Wkst,(DESKTOPENUMPROC)MyEnumDesktopProc,0);  
  262. }  
  263. //--------------------------------------------------------------------------  
  264. void __fastcall TForm3::Button4Click(TObject *Sender)  
  265. {  
  266.     if(ListBox2->ItemIndex == -1)  
  267.     {  
  268.        ShowMessage("请选择一个Desktop");  
  269.        return;  
  270.     }  
  271. HDESK DsktpHandle = OpenDesktop(ListBox1->Items->  
  272.                         Strings[ListBox1->ItemIndex].c_str(),  
  273.                         DF_ALLOWOTHERACCOUNTHOOK,true,  
  274.                         DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  275.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  276.                         DESKTOP_JOURNALPLAYBACK |  
  277.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  278.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);  
  279.     if(!DsktpHandle)  
  280.     {  
  281.        ShowMessage("Open Desktop Error!");  
  282.     }  
  283.     else  
  284.     {  
  285.        SwitchDesktop(DsktpHandle);  
  286.     }  
  287. }  
  288. //--------------------------------------------------------------------------  
  289. void __fastcall TForm3::Button5Click(TObject *Sender)  
  290. {  
  291.     AnsiString WkstName = Edit1->Text;  
  292.     Button3Click(Sender);  
  293.     if( ListBox2->Items->IndexOf(WkstName) != -1)  
  294.     {  
  295.        ShowMessage("这个Work Station已经存在了!");  
  296.     }  
  297.     else  
  298.     {  
  299.        HWINSTA hWkst = CreateWindowStation(WkstName.c_str(),NULL,  
  300.                        WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |  
  301.                        WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |  
  302.                        WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |  
  303.                        WINSTA_READATTRIBUTES | WINSTA_READSCREEN |  
  304.                        WINSTA_WRITEATTRIBUTES,NULL);  
  305.        if(!hWkst)  
  306.        {  
  307.           ShowMessage("Create Wkst Error!");  
  308.        }  
  309.        else  
  310.        {  
  311.           ListBox2->Items->Clear();  
  312.           EnumWindowStations((WINSTAENUMPROC)MyEnumDesktopProc,1);  
  313.        }  
  314.     }  
  315. }  
  316. //--------------------------------------------------------------------------  
  317. void __fastcall TForm3::Button6Click(TObject *Sender)  
  318. {  
  319.     AnsiString DsktpName = Edit2->Text;  
  320.     Button2Click(Sender);  
  321.     if( ListBox1->Items->IndexOf(DsktpName) != -1)  
  322.     {  
  323.        ShowMessage("这个DeskTop已经存在了!");  
  324.     }  
  325.     HDESK DsktpHandle = CreateDesktop(DsktpName.c_str(),NULL,NULL,  
  326.                   DF_ALLOWOTHERACCOUNTHOOK,  
  327.                   DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  328.                   DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL  |  
  329.                   DESKTOP_JOURNALPLAYBACK  |  
  330.                   DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS  |  
  331.                   DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS,  
  332.                   NULL);  
  333.     if(!DsktpHandle)  
  334.     {  
  335.        ShowMessage("DeskTop Creat Error!");  
  336.     }  
  337. }  
  338. //--------------------------------------------------------------------------  
  339. void __fastcall TForm3::Button7Click(TObject *Sender)  
  340. {  
  341.     if(ListBox2->ItemIndex == -1)  
  342.     {  
  343.        ShowMessage("请选择一个Desktop");  
  344.        return;  
  345.     }  
  346. HDESK DsktpHandle = OpenDesktop(ListBox1->Items->  
  347.                         Strings[ListBox1->ItemIndex].c_str(),  
  348.                         DF_ALLOWOTHERACCOUNTHOOK,true,  
  349.                         DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  350.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  351.                         DESKTOP_JOURNALPLAYBACK |  
  352.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  353.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);  
  354.     if(!DsktpHandle)  
  355.     {  
  356.        ShowMessage("Open Desktop Error!");  
  357.     }  
  358.     else  
  359.     {  
  360.        CloseDesktop(DsktpHandle);  
  361.     }  
  362. }  
  363. //---------------------------------------------------------------------------  
  364. void __fastcall TForm3::Button1Click(TObject *Sender)  
  365. {  
  366.     HWINSTA Wkst;  
  367.     if(ListBox2->ItemIndex == -1)  
  368.     {  
  369.        ShowMessage("未选择WorkStation");  
  370.        return;  
  371.     }  
  372. Wkst = OpenWindowStation(ListBox2->Items->  
  373.            Strings[ListBox2->ItemIndex].c_str(),  
  374.            true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |  
  375.            WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |  
  376.            WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |  
  377.            WINSTA_READATTRIBUTES | WINSTA_READSCREEN |  
  378.            WINSTA_WRITEATTRIBUTES);  
  379.     if(Wkst)  
  380.     {  
  381.        bool Res = SetProcessWindowStation(Wkst);  
  382.        if(!Res)  
  383.           ShowMessage("Set Wkst Error!");  
  384.     }  
  385. }  
  386. //--------------------------------------------------------------------------  
  387. void __fastcall TForm3::Button8Click(TObject *Sender)  
  388. {  
  389.     USEROBJECTFLAGS OS;  
  390.     char Info[256];  
  391.     unsigned long ActualLength;  
  392.     HANDLE hHandle = GetProcessWindowStation();  
  393. if( hHandle && GetUserObjectInformation(hHandle,  
  394.              UOI_NAME,Info,256,&ActualLength))  
  395.     {  
  396.        Label6->Caption = Info;  
  397.     }  
  398.     else  
  399.     {  
  400.        Label6->Caption = "Get Info Error!";  
  401.     }  
  402.     hHandle = GetThreadDesktop(GetCurrentThreadId());  
  403. if( hHandle && GetUserObjectInformation(hHandle,  
  404.               UOI_NAME,Info,256,&ActualLength))  
  405.     {  
  406.        Label8->Caption = Info;  
  407.     }  
  408.     else  
  409.     {  
  410.        Label8->Caption = "Get Info Error!";  
  411.     }  
  412.     hHandle = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK,true,  
  413.                         DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |  
  414.                         DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |  
  415.                         DESKTOP_JOURNALPLAYBACK |  
  416.                         DESKTOP_JOURNALRECORD | DESKTOP_READOBJECTS |  
  417.                         DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);  
  418. if( hHandle && GetUserObjectInformation(hHandle,  
  419.              UOI_NAME,Info,256,&ActualLength))  
  420.     {  
  421.        Label10->Caption = Info;  
  422.     }  
  423.     else  
  424.     {  
  425.        Label10->Caption = "Get Info Error!";  
  426.     }  
  427.     STARTUPINFO SI;  
  428.     GetStartupInfo(&SI);  
  429.     Label12->Caption = AnsiString(SI.lpDesktop);  
  430. }  
  431. //--------------------------------------------------------------------------  
  432. void __fastcall TForm3::FormCreate(TObject *Sender)  
  433. {  
  434.     HANDLE hTemp;  
  435.     hTemp = GetProcessWindowStation();  
  436.     USEROBJECTFLAGS OS;  
  437.     char Info[256];  
  438.     unsigned long ActualLength;  
  439.     HANDLE hHandle = GetProcessWindowStation();  
  440.     if( hHandle && GetUserObjectInformation(hTemp,UOI_NAME,Info,256,&ActualLength))  
  441.     {  
  442.        PrivateWkst[0] = Info;  
  443.     }  
  444.     AnsiString Name = "Station";  
  445.     for(int i = 1; i < 8; i++)  
  446.     {  
  447.        PrivateWkst[i] = Name + IntToStr(i);  
  448.        hTemp = CreateWindowStation(PrivateWkst[i].c_str(),NULL,  
  449.                        WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |  
  450.                        WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |  
  451.                        WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |  
  452.                        WINSTA_READATTRIBUTES | WINSTA_READSCREEN |  
  453.                        WINSTA_WRITEATTRIBUTES,NULL);  
  454.     }  
  455. }  
  456. //--------------------------------------------------------------------------  
  457. void __fastcall TForm3::ToolButton1Click(TObject *Sender)  
  458. {  
  459.     int Index = ((TToolButton*)Sender)->Tag;  
  460.     HANDLE Wkst = OpenWindowStation(PrivateWkst[Index].c_str(),  
  461.            true,WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |  
  462.            WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |  
  463.            WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |  
  464.            WINSTA_READATTRIBUTES | WINSTA_READSCREEN |  
  465.            WINSTA_WRITEATTRIBUTES);  
  466.        if(Wkst)  
  467.        {  
  468.           bool Res = SetProcessWindowStation(Wkst);  
  469.           if(!Res)  
  470.           {  
  471.              ShowMessage("Set Wkst Error!");  
  472.           }  
  473.           Button8Click(Sender);  
  474.        }  
  475.     Button8Click(Sender);  
  476. }  
  477. //--------------------------------------------------------------------------  
  478. void __fastcall TForm3::Button9Click(TObject *Sender)  
  479. {  
  480.     Clipboard()->Clear();  
  481. }  
  482. //--------------------------------------------------------------------------  
  483. 头文件如下:  
  484. #ifndef NewDsktpH  
  485. #define NewDsktpH  
  486. //--------------------------------------------------------------------------  
  487. #include <Classes.hpp>  
  488. #include <Controls.hpp>  
  489. #include <StdCtrls.hpp>  
  490. #include <Forms.hpp>  
  491. #include <ExtCtrls.hpp>  
  492. #include <ComCtrls.hpp>  
  493. #include <ToolWin.hpp>  
  494. //--------------------------------------------------------------------------  
  495. class TForm3 : public TForm  
  496. {  
  497. __published:  
  498.     TListBox *ListBox1;  
  499.     TListBox *ListBox2;  
  500.     TLabel *Label1;  
  501.     TLabel *Label2;  
  502.     TButton *Button2;  
  503.     TButton *Button3;  
  504.     TButton *Button4;  
  505.     TPanel *Panel1;  
  506.     TEdit *Edit1;  
  507.     TEdit *Edit2;  
  508.     TButton *Button5;  
  509.     TButton *Button6;  
  510.     TLabel *Label3;  
  511.     TLabel *Label4;  
  512.     TButton *Button7;  
  513.     TButton *Button1;  
  514.     TLabel *Label5;  
  515.     TLabel *Label6;  
  516.     TLabel *Label7;  
  517.     TLabel *Label8;  
  518.     TLabel *Label9;  
  519.     TLabel *Label10;  
  520.     TLabel *Label11;  
  521.     TLabel *Label12;  
  522.     TButton *Button8;  
  523.     TPanel *Panel2;  
  524.     TToolBar *ToolBar1;  
  525.     TToolButton *ToolButton1;  
  526.     TToolButton *ToolButton2;  
  527.     TToolButton *ToolButton3;  
  528.     TToolButton *ToolButton4;  
  529.     TToolButton *ToolButton5;  
  530.     TToolButton *ToolButton6;  
  531.     TToolButton *ToolButton7;  
  532.     TToolButton *ToolButton8;  
  533.     TLabel *Label13;  
  534.     TButton *Button9;  
  535.     void __fastcall Button2Click(TObject *Sender);  
  536.     void __fastcall Button3Click(TObject *Sender);  
  537.     void __fastcall ListBox2Click(TObject *Sender);  
  538.     void __fastcall Button4Click(TObject *Sender);  
  539.     void __fastcall Button5Click(TObject *Sender);  
  540.     void __fastcall Button6Click(TObject *Sender);  
  541.     void __fastcall Button7Click(TObject *Sender);  
  542.     void __fastcall Button1Click(TObject *Sender);  
  543.     void __fastcall Button8Click(TObject *Sender);  
  544.     void __fastcall FormCreate(TObject *Sender);  
  545.     void __fastcall ToolButton1Click(TObject *Sender);  
  546.     void __fastcall Button9Click(TObject *Sender);  
  547. private:  
  548. public:   
  549.     AnsiString  PrivateWkst[8];  
  550.     __fastcall TForm3(TComponent* Owner);  
  551. };  
  552. //--------------------------------------------------------------------------  
  553. extern PACKAGE TForm3 *Form3;  
  554. //--------------------------------------------------------------------------  
  555. #endif  
  556. Dfm文件如下:  
  557. object Form3: TForm3  
  558.   Left = 325  
  559.   Top = 115  
  560.   BorderIcons = [biSystemMenu]  
  561.   BorderStyle = bsSingle  
  562.   Caption = 'Run On New DeskTop'#39's Form'  
  563.   ClientHeight = 366  
  564.   ClientWidth = 622  
  565.   Color = clBtnFace  
  566.   Font.Charset = DEFAULT_CHARSET  
  567.   Font.Color = clWindowText  
  568.   Font.Height = -11  
  569.   Font.Name = 'MS Sans Serif'  
  570.   Font.Style = []  
  571.   OldCreateOrder = False  
  572.   OnCreate = FormCreate  
  573.   PixelsPerInch = 96  
  574.   TextHeight = 13  
  575.   object Label1: TLabel  
  576.     Left = 208  
  577.     Top = 8  
  578.     Width = 66  
  579.     Height = 12  
  580.     Caption = 'Desktop列表'  
  581.     Font.Charset = GB2312_CHARSET  
  582.     Font.Color = clWindowText  
  583.     Font.Height = -12  
  584.     Font.Name = '宋体'  
  585.     Font.Style = []  
  586.     ParentFont = False  
  587.   end  
  588.   object Label2: TLabel  
  589.     Left = 16  
  590.     Top = 8  
  591.     Width = 90  
  592.     Height = 12  
  593.     Caption = 'Workstation列表'  
  594.     Font.Charset = GB2312_CHARSET  
  595.     Font.Color = clWindowText  
  596.     Font.Height = -12  
  597.     Font.Name = '宋体'  
  598.     Font.Style = []  
  599.     ParentFont = False  
  600.   end  
  601.   object Label5: TLabel  
  602.     Left = 400  
  603.     Top = 24  
  604.     Width = 120  
  605.     Height = 12  
  606.     Caption = '当前进程的WokStation'  
  607.     Font.Charset = GB2312_CHARSET  
  608.     Font.Color = clWindowText  
  609.     Font.Height = -12  
  610.     Font.Name = '宋体'  
  611.     Font.Style = []  
  612.     ParentFont = False  
  613.   end  
  614.   object Label6: TLabel  
  615.     Left = 400  
  616.     Top = 48  
  617.     Width = 6  
  618.     Height = 12  
  619.     Caption = ' '  
  620.     Font.Charset = GB2312_CHARSET  
  621.     Font.Color = clWindowText  
  622.     Font.Height = -12  
  623.     Font.Name = '宋体'  
  624.     Font.Style = []  
  625.     ParentFont = False  
  626.   end  
  627.   object Label7: TLabel  
  628.     Left = 400  
  629.     Top = 72  
  630.     Width = 90  
  631.     Height = 12  
  632.     Caption = '当前线程Desktop'  
  633.     Font.Charset = GB2312_CHARSET  
  634.     Font.Color = clWindowText  
  635.     Font.Height = -12  
  636.     Font.Name = '宋体'  
  637.     Font.Style = []  
  638.     ParentFont = False  
  639.   end  
  640.   object Label8: TLabel  
  641.     Left = 400  
  642.     Top = 96  
  643.     Width = 6  
  644.     Height = 12  
  645.     Caption = ' '  
  646.     Font.Charset = GB2312_CHARSET  
  647.     Font.Color = clWindowText  
  648.     Font.Height = -12  
  649.     Font.Name = '宋体'  
  650.     Font.Style = []  
  651.     ParentFont = False  
  652.   end  
  653.   object Label9: TLabel  
  654.     Left = 400  
  655.     Top = 120  
  656.     Width = 108  
  657.     Height = 12  
  658.     Caption = '当前Input的DeskTop'  
  659.     Font.Charset = GB2312_CHARSET  
  660.     Font.Color = clWindowText  
  661.     Font.Height = -12  
  662.     Font.Name = '宋体'  
  663.     Font.Style = []  
  664.     ParentFont = False  
  665.   end  
  666.   object Label10: TLabel  
  667.     Left = 400  
  668.     Top = 144  
  669.     Width = 6  
  670.     Height = 12  
  671.     Caption = ' '  
  672.     Font.Charset = GB2312_CHARSET  
  673.     Font.Color = clWindowText  
  674.     Font.Height = -12  
  675.     Font.Name = '宋体'  
  676.     Font.Style = []  
  677.     ParentFont = False  
  678.   end  
  679.   object Label11: TLabel  
  680.     Left = 400  
  681.     Top = 168  
  682.     Width = 102  
  683.     Height = 12  
  684.     Caption = '程序的启动DeskTop'  
  685.     Font.Charset = GB2312_CHARSET  
  686.     Font.Color = clWindowText  
  687.     Font.Height = -12  
  688.     Font.Name = '宋体'  
  689.     Font.Style = []  
  690.     ParentFont = False  
  691.   end  
  692.   object Label12: TLabel  
  693.     Left = 400  
  694.     Top = 192  
  695.     Width = 6  
  696.     Height = 12  
  697.     Caption = ' '  
  698.     Font.Charset = GB2312_CHARSET  
  699.     Font.Color = clWindowText  
  700.     Font.Height = -12  
  701.     Font.Name = '宋体'  
  702.     Font.Style = []  
  703.     ParentFont = False  
  704.   end  
  705.   object Label13: TLabel  
  706.     Left = 520  
  707.     Top = 240  
  708.     Width = 90  
  709.     Height = 12  
  710.     Caption = '切换WorkStation'  
  711.     Font.Charset = GB2312_CHARSET  
  712.     Font.Color = clWindowText  
  713.     Font.Height = -12  
  714.     Font.Name = '宋体'  
  715.     Font.Style = []  
  716.     ParentFont = False  
  717.   end  
  718.   object ListBox1: TListBox  
  719.     Left = 208  
  720.     Top = 24  
  721.     Width = 177  
  722.     Height = 161  
  723.     ItemHeight = 13  
  724.     TabOrder = 0  
  725.   end  
  726.   object ListBox2: TListBox  
  727.     Left = 16  
  728.     Top = 24  
  729.     Width = 177  
  730.     Height = 161  
  731.     ItemHeight = 13  
  732.     TabOrder = 1  
  733.     OnClick = ListBox2Click  
  734.   end  
  735.   object Button2: TButton  
  736.     Left = 16  
  737.     Top = 320  
  738.     Width = 75  
  739.     Height = 25  
  740.     Caption = '枚举DskTp'  
  741.     TabOrder = 2  
  742.     OnClick = Button2Click  
  743.   end  
  744.   object Button3: TButton  
  745.     Left = 112  
  746.     Top = 320  
  747.     Width = 75  
  748.     Height = 25  
  749.     Caption = '枚举Wkst'  
  750.     TabOrder = 3  
  751.     OnClick = Button3Click  
  752.   end  
  753.   object Button4: TButton  
  754.     Left = 208  
  755.     Top = 320  
  756.     Width = 75  
  757.     Height = 25  
  758.     Caption = '切换DskTp'  
  759.     TabOrder = 4  
  760.     OnClick = Button4Click  
  761.   end  
  762.   object Panel1: TPanel  
  763.     Left = 16  
  764.     Top = 192  
  765.     Width = 369  
  766.     Height = 113  
  767.     BevelInner = bvSpace  
  768.     BevelOuter = bvLowered  
  769.     TabOrder = 5  
  770.     object Label3: TLabel  
  771.       Left = 16  
  772.       Top = 80  
  773.       Width = 78  
  774.       Height = 12  
  775.       Caption = 'Desktop名称:'  
  776.       Font.Charset = GB2312_CHARSET  
  777.       Font.Color = clWindowText  
  778.       Font.Height = -12  
  779.       Font.Name = '宋体'  
  780.       Font.Style = []  
  781.       ParentFont = False  
  782.     end  
  783.     object Label4: TLabel  
  784.       Left = 16  
  785.       Top = 32  
  786.       Width = 102  
  787.       Height = 12  
  788.       Caption = 'Workstation名称:'  
  789.       Font.Charset = GB2312_CHARSET  
  790.       Font.Color = clWindowText  
  791.       Font.Height = -12  
  792.       Font.Name = '宋体'  
  793.       Font.Style = []  
  794.       ParentFont = False  
  795.     end  
  796.     object Edit1: TEdit  
  797.       Left = 120  
  798.       Top = 24  
  799.       Width = 121  
  800.       Height = 21  
  801.       TabOrder = 0  
  802.     end  
  803.     object Edit2: TEdit  
  804.       Left = 120  
  805.       Top = 72  
  806.       Width = 121  
  807.       Height = 21  
  808.       TabOrder = 1  
  809.     end  
  810.     object Button5: TButton  
  811.       Left = 272  
  812.       Top = 21  
  813.       Width = 75  
  814.       Height = 25  
  815.       Caption = '创建Wkst'  
  816.       TabOrder = 2  
  817.       OnClick = Button5Click  
  818.     end  
  819.     object Button6: TButton  
  820.       Left = 272  
  821.       Top = 69  
  822.       Width = 75  
  823.       Height = 25  
  824.       Caption = '创建Dsktp'  
  825.       TabOrder = 3  
  826.       OnClick = Button6Click  
  827.     end  
  828.   end  
  829.   object Button7: TButton  
  830.     Left = 304  
  831.     Top = 320  
  832.     Width = 75  
  833.     Height = 25  
  834.     Caption = '关闭Dsktp'  
  835.     TabOrder = 6  
  836.     OnClick = Button7Click  
  837.   end  
  838.   object Button1: TButton  
  839.     Left = 408  
  840.     Top = 280  
  841.     Width = 75  
  842.     Height = 25  
  843.     Caption = '切换Wkst'  
  844.     Enabled = False  
  845.     TabOrder = 7  
  846.     OnClick = Button1Click  
  847.   end  
  848.   object Button8: TButton  
  849.     Left = 408  
  850.     Top = 240  
  851.     Width = 75  
  852.     Height = 25  
  853.     Caption = '获取信息'  
  854.     TabOrder = 8  
  855.     OnClick = Button8Click  
  856.   end  
  857.   object Panel2: TPanel  
  858.     Left = 520  
  859.     Top = 271  
  860.     Width = 77  
  861.     Height = 51  
  862.     BevelInner = bvSpace  
  863.     BevelOuter = bvLowered  
  864.     TabOrder = 9  
  865.     object ToolBar1: TToolBar  
  866.       Left = 2  
  867.       Top = 2  
  868.       Width = 73  
  869.       Height = 47  
  870.       Align = alNone  
  871.       ButtonHeight = 23  
  872.       ButtonWidth = 14  
  873.       Caption = 'ToolBar1'  
  874.       EdgeBorders = []  
  875.       Flat = True  
  876.       Font.Charset = ANSI_CHARSET  
  877.       Font.Color = clWindowText  
  878.       Font.Height = -12  
  879.       Font.Name = 'Courier New'  
  880.       Font.Style = []  
  881.       ParentFont = False  
  882.       ShowCaptions = True  
  883.       TabOrder = 0  
  884.       object ToolButton1: TToolButton  
  885.         Left = 0  
  886.         Top = 0  
  887.         AutoSize = True  
  888.         Caption = '1'  
  889.         Down = True  
  890.         Grouped = True  
  891.         ImageIndex = 0  
  892.         Style = tbsCheck  
  893.         OnClick = ToolButton1Click  
  894.       end  
  895.       object ToolButton2: TToolButton  
  896.         Tag = 1  
  897.         Left = 18  
  898.         Top = 0  
  899.         AutoSize = True  
  900.         Caption = '2'  
  901.         Grouped = True  
  902.         ImageIndex = 1  
  903.         Style = tbsCheck  
  904.         OnClick = ToolButton1Click  
  905.       end  
  906.       object ToolButton3: TToolButton  
  907.         Tag = 2  
  908.         Left = 36  
  909.         Top = 0  
  910.         AutoSize = True  
  911.         Caption = '3'  
  912.         Grouped = True  
  913.         ImageIndex = 2  
  914.         Style = tbsCheck  
  915.         OnClick = ToolButton1Click  
  916.       end  
  917.       object ToolButton4: TToolButton  
  918.         Tag = 3  
  919.         Left = 54  
  920.         Top = 0  
  921.         AutoSize = True  
  922.         Caption = '4'  
  923.         Grouped = True  
  924.         ImageIndex = 3  
  925.         Wrap = True  
  926.         Style = tbsCheck  
  927.         OnClick = ToolButton1Click  
  928.       end  
  929.       object ToolButton5: TToolButton  
  930.         Tag = 4  
  931.         Left = 0  
  932.         Top = 23  
  933.         AutoSize = True  
  934.         Caption = '5'  
  935.         Grouped = True  
  936.         ImageIndex = 4  
  937.         Style = tbsCheck  
  938.         OnClick = ToolButton1Click  
  939.       end  
  940.       object ToolButton6: TToolButton  
  941.         Tag = 5  
  942.         Left = 18  
  943.         Top = 23  
  944.         AutoSize = True  
  945.         Caption = '6'  
  946.         Grouped = True  
  947.         ImageIndex = 5  
  948.         Style = tbsCheck  
  949.         OnClick = ToolButton1Click  
  950.       end  
  951.       object ToolButton7: TToolButton  
  952.         Tag = 6  
  953.         Left = 36  
  954.         Top = 23  
  955.         AutoSize = True  
  956.         Caption = '7'  
  957.         Grouped = True  
  958.         ImageIndex = 6  
  959.         Style = tbsCheck  
  960.         OnClick = ToolButton1Click  
  961.       end  
  962.       object ToolButton8: TToolButton  
  963.         Tag = 7  
  964.         Left = 54  
  965.         Top = 23  
  966.         AutoSize = True  
  967.         Caption = '8'  
  968.         Grouped = True  
  969.         ImageIndex = 7  
  970.         Style = tbsCheck  
  971.         OnClick = ToolButton1Click  
  972.       end  
  973.     end  
  974.   end  
  975.   object Button9: TButton  
  976.     Left = 408  
  977.     Top = 320  
  978.     Width = 75  
  979.     Height = 25  
  980.     Caption = '清空剪切板'  
  981.     TabOrder = 10  
  982.     OnClick = Button9Click  
  983.   end  

  1. end  

上文来自:http://blog.csdn.net/linux7985/article/details/5694672

你可能感兴趣的:(C++,c,windows,api,VC)