Autor Beitrag
Dezipaitor
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 220



BeitragVerfasst: Fr 02.02.07 21:40 
hi,

ich habe eine Unit geschrieben, die es ermöglicht eigene Windows Desktops zu verwalten.

Die Units sind von mir (bis auf compilers.inc) und in ANSI und Unicode aufgeteilt.
So ziemlich alles ist in Englisch kommentiert und auch mit Beispielen versehen.

Die verwendete Lizenz ist Creative Commons
# Namensnennung. Sie müssen den Namen des Autors/Rechtsinhabers nennen.
# Keine kommerzielle Nutzung. Dieser Inhalt darf nicht für kommerzielle Zwecke verwendet werden.
# Weitergabe unter gleichen Bedingungen. Wenn Sie diesen Inhalt bearbeiten oder in anderer Weise umgestalten, verändern oder als Grundlage für einen anderen Inhalt verwenden, dann dürfen Sie den neu entstandenen Inhalt nur unter Verwendung identischer Lizenzbedingungen weitergeben.

1. Achtung!
Die aktuelle Version ist noch im Betastatus, da ich noch nicht lange Testen konnte.

2. Achtung!
Teste deine Desktopverwaltung auf einem zweiten PC oder in einer VM (auch über Remotedebugging). Sollte dein Programm unter Delphi eine Exception werfen, so zeigt Delphi die Quellcodezeile an. Da jedoch der Desktop in diesem Moment nicht zurückgesetzt wird, kommst du nicht zu Delphi und kannst daher auch nicht fortsetzen.
Der Desktop wird automatisch geschlossen, sobald deine Anwendung beendet wird.
Man kann daher auch über Telnet (o.Ä.) die Anwendung abschießen.

Bekannte Bugs :
In einigen Fällen bekomme ich bei der Erstellung eines neuen Desktops die Ausnahmen, dass nicht genügend Speicher zur Verfügung steht.
Ein Auszug aus CreateDesktop beschreibt vermutlich die Ursache.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
The number of desktops that can be created is limited by the size of the system desktop heap, which is 48 MB. Desktop objects use the heap to store resources. You can increase the number of desktops that can be created by reducing the default heap reserved for each desktop in the interactive window station. This value is specified in the SharedSection substring of the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Windows. The default data for this registry value is as follows:

%SystemRoot%\system32\csrss.exe ObjectDirectory=\Windows 
SharedSection=1024,3072,512 
Windows=On SubSystemType=Windows ServerDll=basesrv,1 
ServerDll=winsrv:UserServerDllInitialization,3 
ServerDll=winsrv:ConServerDllInitialization,2 
ProfileControl=Off MaxRequestThreads=16

The first SharedSection value is the size of the shared heap common to all desktops, 
in kilobytes. The second SharedSection value is the size of the desktop heap needed 
for each desktop that is created in the interactive window station, WinSta0, in 
kilobytes. The third SharedSection value is the size of the desktop heap needed 
for each desktop that is created in a noninteractive window station, in kilobytes.


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
   {TDesktop is the main class that provides methods to create, open
    and manipulate desktops.
  Be aware of following things: 
   1. nearly every function can create an exception. 
    If you don't check for them it can happen that a switch back to default desktop does not work.
    This especially happens if Delphi is active and shows the exception source on the default desktop.
   2. This instance does not dynamically react on changes done by direct WinAPI calls.
   }

  TDesktop = class(TPersistent)
   public
     { public declarations }
   {Constructor Create creates a new instance of TDesktop.
    Create can create or open a desktop object. 
    
    @param(aParent Contains the parent instance that administer the desktop.
             You can set it to nil if you want to administer the desktop yourself. In that case you
             must free it by yourself. 
       In the other case you must not call Free because TDesktops(aParent) calls it if it freed.
    
    @param(aFlag Contains the type of work you want to do : Create or Open a desktop. See @See(TDesktopFlags) for more information.
    @param(aCloseOnDestroy Contains a flag that determines if the desktop handle shall be closed if the desktop instance is freed.
            That case is used if aCloseOnDestroy is TRUE otherwise the handle will exists until you close it by yourself or
         the application is closed.
    @param(aName Contains the name of an existing Desktop. A desktop name is case sensitive.)
    @param(DesktopFlags Contains flags for desktop opening. See @link(TDesktopFlags) for more information) 
    @param(doInherit )
    @param(aDesirecAccess Contains flags that defines the type of opening. You can use the following flags
       concatenated by OR-Operator :
         READ_CONTROL, WRITE_DAC, WRITE_OWNER, STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE,
       STANDARD_RIGHTS_ALL, SPECIFIC_RIGHTS_ALL, ACCESS_SYSTEM_SECURITY, MAXIMUM_ALLOWED, GENERIC_READ,
       GENERIC_WRITE, GENERIC_EXECUTE, GENERIC_ALL,
       // Desktop-specific access flags 
       DESKTOP_READOBJECTS, DESKTOP_CREATEWINDOW, DESKTOP_CREATEMENU, DESKTOP_HOOKCONTROL, DESKTOP_JOURNALRECORD
       DESKTOP_JOURNALPLAYBACK, DESKTOP_ENUMERATE, DESKTOP_WRITEOBJECTS
     You can look up the meanings in MSDN.)
    @param(aSecurityDescriptor Contains security aspects to be assigned to the new desktop. Set to nil if the security attributes
           of the application shall be used.)  
    @raises(Create raises ECreateDesktopException with an error description if the desktop could not be created.
             Create raises EOpenDesktopException with an error description if the desktop could not be opened
             Create raises EDesktopException if the desktop is already opened by this instance.)
   
   }

     constructor Create(const aParent : TDesktops;
                        const aFlag : TCreationFlag;
                        const aCloseOnDestroy : Boolean;
                        const aName : WideString;
                        const DesktopFlags : TDesktopFlags;
                        const doInherit : Boolean;
                        const aDesiredAccess : ACCESS_MASK;
                        const aSecurityDescriptor : PSECURITYATTRIBUTES);

     {CreateUnInitialized creates a desktop instance without creating or opening a desktop.
    This function is used for internal purposes and should not be used.
   }

     constructor CreateUnInitialized(const aParent : TDesktops;
                              const aName : WideString);

     {Destroy frees the desktop instance and closes the desktop handle if any and if the 
      property OnDestroyDesktop is true.
      If OnDestroyDesktop is false the desktop instance is freed but the desktop handle is retained. }

     destructor Destroy; override;
   

   {OpenDesktopByName opens a desktop with the name given in the property Name.
    This function does not check for an already opened desktop in this instance.
     It simply overrides the current handle of this desktop instance.
    For more information about parameters see @see(Create).
    
    Do not use this function, it is used for internal purposes.}

     function OpenDesktopByName(const DesktopFlags : TDesktopFlags;
                          const doInherit : Boolean;
                          const aDesiredAccess : ACCESS_MASK) : HDESK; overloadvirtual;


     {DesktopFlagsToInt converts the enum type TDesktopFlags to the corresponding
    integer type. 
    @parameter( @see(TDesktopFlags) for more Information)
    @return(Returns Windows.DF_ALLOWOTHERACCOUNTHOOK (as integer) if [DF_ALLOWOTHERACCOUNTHOOK] was supplied
      otherise it returns zero.}

     function DesktopFlagsToInt(DesktopFlags : TDesktopFlags) : Cardinal;

     {GetDesktopWindowHandles creates a list of available desktop window handles.
    All TList pointers are desktop handles. You can convert them to HDESK by type cast :
        HDESK(List.Item[i])
      @return(Returns a list of desktop handles. The return value can never be nil and therfore
         must be freed by the caller. }

     function GetDesktopWindowHandles : TList; virtual;

     {OpenInputDesktop opens the desktop that currently holds the input.
    This function does check for an already opened desktop in this instance and raises an EOpenDesktop Error
     It simply overrides the current handle of this desktop instance.
    For more information about parameters see @see(Create).
    
    Do not use this function, it is used for internal purposes.
    
    @raises(OpenInputDesktop raises EOpenDesktopException with an error description if the desktop could not be opened
             OpenInputDesktop raises EDesktopException if the desktop is already opened by this instance.)}

     function OpenInputDesktop(const DesktopFlags : TDesktopFlags;
                          const doInherit : Boolean;
                          const aDesiredAccess : ACCESS_MASK) : HDESK; virtual;

     {Close frees a desktop handle. The instance cannot be used for more desktop manipulation.
    @raises(ECloseDesktopException can be raised with furhter information 
        if the desktop is already closed or an error occurred.}

     procedure Close;
   
   {SetThreadDesktop assigns the desktop to the thread that calls this function.
    This only works if the thread has no already opened windows or hooks.
    If the desktop is not opened this function does nothing.
    @raises(EDesktopException can be raised if an error occured)}

     procedure SetThreadDesktop;
   
   {SwitchDesktop switches input to the desktop of this instance.
    If no desktop is opened this function does nothing.
    
   SwitchDesktop does save a handle to the desktop that was active before it is called so
    it can be changed back in @link(SwitchDesktopBack)
     @raises(EDesktopException can be raised if an error occured while switching desktop)}

     procedure SwitchDesktop;
   
   {SwitchDesktopBack switches the input to the desktop used before @link(SwitchDesktop) was called.
    @raises(EDesktopException can be raised if an error occured while switching desktop)}

     procedure SwitchDesktopBack;


   published
     { published declarations }
   {The readonly property Name contains the name of the Desktops. Be aware that desktop names are case sensitive.} 
     property Name : WideString read GetName;
   {The readonly property DesiredAccess contains the access mask specified by the parameter aDesiredAccess in @link(Create)}
     property DesiredAccess : ACCESS_MASK read fDesiredAccess;
   {The readonly property SecurityDescriptor contains the SecurityDescriptor specified by the parameter aSecurityDescriptor in @link(Create)}
     property SecurityDescriptor : TSECURITYATTRIBUTES read RetrieveSD;
   {The readonly property Handle contains the handle to the desktop. It can be 0 if the desktop is not opened or invald.
    Be aware that an access to this handle can result to unexpected results. }

     property Handle : HDESK read fHandle;
   {The property Desktops flags gets or sets the desktop flag.
    If no desktop is opened a change of this flag is ignored.
    EDesktopException can be raised if an error occures while setting flag.}

     property DesktopFlags : TDesktopFlags read GetDesktopFlags write SetDesktopFlags;
   
   {The property returns true if this desktop instance was created by OpenInputDesktop; otherwise false.}
     property IsInputDesktop : Boolean read fIsInputDesktop;

   {The property Parent returns the parameter aParent in in @link(Create).}
     property Parent : TDesktops read fParent;
   
   {The property CloseOnDestroy is a flag that determines if the desktop handle shall be closed if the desktop instance is freed.
     That case is used if aCloseOnDestroy is TRUE otherwise the handle will exists until you close it by yourself or
     the application is closed.}

     property CloseOnDestroy : Boolean read fCloseOnDestroy write fCloseOnDestroy;

     
     {The readonly property Opened gets the status of the desktop handle.
      If the desktop handle is not zero it returns true.
    Opened cannot determine a open status of a desktop that was closed by a winapi call.
   }

     property Opened : Boolean read GetOpened;
   
   {The event property OnDestroyDesktop is called if the desktop instance is destroyed.
      See @link(TOnDestroyDesktop) for more information. }

   property OnDestroyDesktop : TOnDestroyDesktop read fOnDestroyDesktop write fOnDestroyDesktop;
   end;


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
 {TDesktops is a administrative class that contains a list of desktops and
    methodes to manipulate desktops.
  All TDesktop instances that are created and assigned to this class are
  automatically freed if this instance is freed.}

   TDesktops = class(TComponent)
   public
     { public declarations }
   {Create creates a new instance of TDesktop.
    @param(AOwner contains the parent of this TDesktops component. If you set it to another component
            the TDesktops instance and all its sub desktops are freed automatically.}

     constructor Create(AOwner: TComponent); override;
   
   {Destroy frees the TDektops instance.}
     destructor Destroy; override;

     {Clear removes all desktops that are administered by this instance.}
     procedure Clear; virtual;

 
     {FindDesktopByName searches for a desktop with the given name.
    The search is case sensitive.
    @param(Name contains the desktop name)
    @return(Returns the instance of the desktop with the given name.
           If this TDesktops instance does not hold a desktop instance with the given name
        it returns nil. That does not mean there is no desktop with that name.)}

     function FindDesktopByName(const Name : WideString) : TDesktop; virtual;
   
   {FindDesktopByHandle searches for a desktop in the TDesktops list that has the same handle.
    This function even searches desktops administerd by this instance even if they are closed.
    In this case it temporarily opens the desktop and closes it again.
   @param(Handle contains the handle to be searched for)
   @return(Returns the instance of desktop to be found; otherwise found if the desktop is not in list of
          TDesktops)}

     function FindDesktopByHandle(const Handle : HDESK) : TDesktop; virtual;
   
   {FindInputDesktop searches for the desktop that was created with OpenInputDesktop.
    
    Developer warning: 
      Actually this function returns the first desktop that was created/opened by OpenInputDesktop 
    and not the actual real input desktop.
    TODO: change behaviour  
   }

     function FindInputDesktop : TDesktop; virtual;

     {Update updates the internal desktop list.
    Some or all pointers to the desktops (TDesktop) can be invalid!
    
    This function removes all desktop instances that are no longer valid on the window station.
    If there are added new desktops new TDesktop instanced are added to the list.
    }

     procedure Update;
   
   
   
     {CreateDesktop creates a new desktop and adds it to the list (if successfull).
     
    @param(aName Contains the name of an existing Desktop. A desktop name is case sensitive.)
    @param(DesktopFlags Contains flags for desktop opening. See @link(TDesktopFlags) for more information) 
    @param(doInherit )
    @param(aDesirecAccess Contains flags that defines the type of opening. You can use the following flags
       concatenated by OR-Operator :
         READ_CONTROL, WRITE_DAC, WRITE_OWNER, STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE,
       STANDARD_RIGHTS_ALL, SPECIFIC_RIGHTS_ALL, ACCESS_SYSTEM_SECURITY, MAXIMUM_ALLOWED, GENERIC_READ,
       GENERIC_WRITE, GENERIC_EXECUTE, GENERIC_ALL,
       // Desktop-specific access flags 
       DESKTOP_READOBJECTS, DESKTOP_CREATEWINDOW, DESKTOP_CREATEMENU, DESKTOP_HOOKCONTROL, DESKTOP_JOURNALRECORD
       DESKTOP_JOURNALPLAYBACK, DESKTOP_ENUMERATE, DESKTOP_WRITEOBJECTS
     You can look up the meanings in MSDN.
     You must at least use the flag DESKTOP_CREATEWINDOW.)
     @param(aSecurityDescriptor Contains security aspects to be assigned to the new desktop)
     @return(CreateDesktop returns a handle to the desktop)
     @raises(CreateDesktop raises ECreateDesktopException with an error description if the desktop could not be created.)
          
   }

     function CreateDesktop(const Name : WideString;
                            const DesktopFlags : TDesktopFlags;
                                   const aDesiredAccess : ACCESS_MASK;
                                   const aSecurityDescriptor : PSECURITYATTRIBUTES) : TDesktop; virtual;
  

                 
  { OpenDesktop opens an existing desktop and adds it to the list (if successfull).
    
    It calls the WinAPI function OpenDesktop. See more information in MSDN.
    @param(aName Contains the name of an existing Desktop. A desktop name is case sensitive.)
    @param(DesktopFlags Contains flags for desktop opening. See @link(TDesktopFlags) for more information) 
    @param(doInherit )
    @param(aDesirecAccess Contains flags that defines the type of opening. You can use the following flags
       concatenated by OR-Operator :
         READ_CONTROL, WRITE_DAC, WRITE_OWNER, STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE,
       STANDARD_RIGHTS_ALL, SPECIFIC_RIGHTS_ALL, ACCESS_SYSTEM_SECURITY, MAXIMUM_ALLOWED, GENERIC_READ,
       GENERIC_WRITE, GENERIC_EXECUTE, GENERIC_ALL,
       // Desktop-specific access flags 
       DESKTOP_READOBJECTS, DESKTOP_CREATEWINDOW, DESKTOP_CREATEMENU, DESKTOP_HOOKCONTROL, DESKTOP_JOURNALRECORD
       DESKTOP_JOURNALPLAYBACK, DESKTOP_ENUMERATE, DESKTOP_WRITEOBJECTS
     You can look up the meanings in MSDN.)
     @return(OpenDesktop returns a handle to the desktop)
     @raises(OpenDesktop raises EOpenDesktopException with an error description if the desktop could not be opened
             OpenDesktop raises EDesktopException if the desktop is already opened by this instance.)

  }
                 
     function OpenDesktop(const Name : WideString;
                          const DesktopFlags : TDesktopFlags;
                                   const aDesiredAccess : ACCESS_MASK;
                                   const doInherit : Boolean) : TDesktop; virtual;
                   
  
     {OpenInputDesktop opens the desktop that currently holds the input and adds it to the list (if successfull)
    This function does check for an already opened desktop in this instance and raises an EOpenDesktop Error
     It simply overrides the current handle of this desktop instance.
    For more information about parameters see @see(Create).
    
    Do not use this function, it is used for internal purposes.
    
    @raises(OpenInputDesktop raises EOpenDesktopException with an error description if the desktop could not be opened
             OpenInputDesktop raises EDesktopException if the desktop is already opened by this instance.)}
                 
     function OpenInputDesktop(const DesktopFlags : TDesktopFlags;
                                const aDesiredAccess : ACCESS_MASK;
                               const doInherit : Boolean) : TDesktop; virtual;

     
   {GetThreadDesktop returns the desktop that is assigned to the thread given in ThreadID.
    @param(ThreadID contains the thread ID that is used to determine which desktop is assigned to the Thread.
         You can set ThreadID to zero if the current thread shall be used.)
    @return(Returns the desktop instance that is assigned to the given thread or 
             nil if no desktop could be found in TDesktops list.
         
    @raises(GetThreadDesktop raises EDesktopException if the given thread does not have a desktop)
    }

     function GetThreadDesktop(ThreadID : Cardinal = 0) : TDesktop;

     {The class function GetDesktopName returns the name of the desktop identified by its handle
    @param(deskt contains the handle value to the desktop)
    @return(Returns the name of the desktop as a unicode string. The return value is a zero string
            if no desktop name could be retrieved.)
   }

     class function GetDesktopName(const desk : HDESK) : WideString;

     {GetDesktops creates a unicode stringlist that contains all desktop names.
    @param(WindowStation contains the window station that shall be used to get the desktop names.
      You can set it to zero if you want to use the window station of the process.
    @return(Returns always a none nil Stringlist.)
    @raises(EDesktopException can be raised if an error occurs)
   }

     class function GetDesktops(WindowStation : HWINSTA) : TTntStringList; overloadvirtual;

     {GetDesktopHeapSize returns the maximum heap size of the desktop heap.
    @return(Returns the heap size in bytes)
    @raises(If an error occurs EDesktopException will be raised)}

     class function GetDesktopHeapSize : Cardinal; virtual;
   published
     { published declarations }
   
   {The readonly property Desktops contains all desktops that are administered by this instance.
    Be aware that pointers to the instances can be made invalid.}

     property Desktops : tObjectlist read fDesktops;
   
   {The event property OnDestroyDesktop replaces OnDestroyDesktop of TDesktop if both 
     (TDesktop and TDesktops) events are not nil.
    This happens in @link(Clear) method.}

     property OnDestroyDesktop : TOnDestroyDesktop read fOnDestroyDesktop write fOnDestroyDesktop;


   end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
   var Desktops : TDesktops;
       MyDesktop  : TDesktop;
   begin
     Desktops := TDesktops.Create(nil);
   MyDesktop := Desktops.CreateDesktop()
   
     MyDesktop := Desktops.CreateDesktop('MyDesktop1' ,[], GENERIC_ALL,nil);

     if Assigned(MyDesktop) then
     try
       MyDesktop.SwitchDesktop;
       MyDesktop.SetThreadDesktop;
   
       ...do you stuff  here...
     finally
       MyDesktop.SwitchDesktopBack;
       MyDesktop.SetThreadDesktop;
   end;
   
   Desktops.Free; //myDesktop is freed here
   Desktops := nil;
   end;


Demo
Angehängt habe ich ein Beispielprogram mit VCL und KOL (kolmck.net/).
Das Programm zeigt auf dem Hauptdesktop ein VCL Formular an mit dem man einen Desktop erstellen kann.
Auf dem neuen Desktop wird dann mit KOL ein neues Fenster in einem neuen Thread erstellt. Im Hintegrund wird ein eingegrautes Bild des alten Desktops dargestellt, so dass der Benutzer sich nicht wundert, warum alle seine Anwendungen verschwunden sind.
Dieses Verhalten sieht man auch in Vista.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von Dezipaitor am So 01.04.07 21:01, insgesamt 6-mal bearbeitet
matze
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Fr 02.02.07 23:58 
Hallo,
könntest du evtl. ein kleines Demo-Projekt mit anhängen, damit man auch weiß wie man die Unit zu benutzen hat.

Danke.
Karlson
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 2088



BeitragVerfasst: Sa 17.02.07 03:31 
In Zukunft würde ich eine kompilierte Exe mit ins Demoprojekt legen.
Dann kann man nämlich gleich sehen ob es sich lohnt die Unit zu installieren.

Weil allgemein hört sich das ganz intressant an ;)
matze
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 4613
Erhaltene Danke: 24

XP home, prof
Delphi 2009 Prof,
BeitragVerfasst: Sa 17.02.07 11:48 
ja da muss ich dir Recht geben.

@Dezipaitor: Bitte hänge doch noch eine kompilierte Exe an, damit man sich nicht zum testen extra noch KOL installieren muss.

_________________
In the beginning was the word.
And the word was content-type: text/plain.
Dezipaitor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 220



BeitragVerfasst: Sa 31.03.07 22:21 
KOL muss nicht installiert werden. Runterladen und in den Suchpfad einfügen - fertig.

Eine EXE Datei habe ich deshalb nicht beigelegt, weil die DEMO sinnlos wäre. Desktop wechseln,Nachrichtenbox anzeigen und dann wieder zurück.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 01.04.07 14:17 
Ich würde mich auch über eine compilierte Version der Demo freuen.

Selbst wenn die Demo nur kurz den Desktop wechselt, so reicht das aus, dass man damit ein wenig spielen kann. ...

Ansonsten ein paar Ideen, was die Demo noch machen könnte:
- Verfügbare Desktops auslesen
- auf diese Wechseln
- Neue anlegen \ vorhandene löschen
- Fenster zwischen Desktops verschieben ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Dezipaitor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 220



BeitragVerfasst: So 01.04.07 21:10 
Anbei die ausführbare DEMO zum Desktopwechseln.

Ich muss jedoch ausdrüchklich darauf hinweisen, dass vor dem Starten der Anwendung, alle Daten gespeichert werden müssen.

user profile iconBenBE hat folgendes geschrieben:
Ansonsten ein paar Ideen, was die Demo noch machen könnte:
- Verfügbare Desktops auslesen
- auf diese Wechseln
- Neue anlegen \ vorhandene löschen
- Fenster zwischen Desktops verschieben ...


+ Verfügbare Desktops auslesen
> Auslesen der Desktops der aktuellen Winstation ist drin
+ auf diese Wechseln
> Wechseln hier nicht möglich, da die Standarddesktops geschützt sind (man kann auch eigene Desktops so schützen)
Andere Desktops würden natürlich funkzen.
+ Neue anlegen \ vorhandene löschen
> Eine Desktopverwaltung kann jeder selbst schreiben :D. Der Witz an der Sache ist, dass man in einem neuen Desktop einfach den Explorer aufrufen muss, um die Startleiste zu erhalten.
Ein Programm (in Delphi) dazu findet man dort : sourceforge.net/projects/virtual-desktop

+ Fenster zwischen Desktops verschieben
> Das ist nicht möglich, weil sobald ein Prozess (oder Thread) auf einen Desktop ersteinmal ein Fenster erstellt hat, dieses nicht mehr auf einen anderen Desktop gebracht werden kann.
D.h. jeder Thread (auch der Prozessthread) kann nur dann ein Fenster auf einen Desktop erstellen, wenn er nicht bereits auf einem anderen Desktop Fenster erstellt hat. Also pro Desktop braucht ein Programm einen Thread mit der Ausgabe. Und da die VCL völlig Thread inkompatibel ist (auch mit Syncronize!!!!), muss man nonVCL programmieren (habs mit KOL gemacht).
\\BBG//
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 21

Win XP Pro SP2, Win 2000 Pro SP4
Delphi 7 Enterprise
BeitragVerfasst: Mo 09.04.07 21:50 
Könnte man nicht die gesamte Anwendung mittels Codeinjection dazu "überreden", auf einen anderen Desktop zu wandern?

_________________
"Irren ist menschlich. Aber wenn man richtig Mist bauen will, braucht man einen Computer."
(Dan Rather, CBS-Fernsehreporter)
Dezipaitor Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 220



BeitragVerfasst: Di 10.04.07 09:49 
Naja, wenn du es schaffst damit die Fensterhandles zu schließen, und dann auf dem neuen Desktop erneut die Fenster zu erstellen und darzustellen, dann würde das wohl schon gehen.
Aber selbst das Schließen von Fenstern in der VCL bringt nichts, weil da immernoch irgendwas an Handles geöffnet ist. Das erstmal rauszufinden ist schon zu aufwendig.