More clearly introduces the reserved namespace extension (reproduced)

xiaoxiao2021-03-06  15

Transfer from the pug

Shell namespace extension

General introduction

Many people must use zipmagic, which is very strange to map a compressed file into a folder. I don't know what technology it uses. It is actually the technology it uses to achieve a housing of the shell (Shell Namespace Extension) ).

Folders and views: the basic structure of the resource manager

The interface of the resource manager is displayed for two parts: The left is displayed on the left, which is displayed in the tree structure, which usually believes that the left is displayed on the file directory tree, but in fact, there are a lot of display on the left. It is not the enclosure object of the file directory, such as the control panel, printer, etc. Details of the object, when the directory is selected, the file in the directory is displayed. When the control panel is selected, the control panel item is displayed on the right. This is the folder and view structure.

Folder interaction with the manager

The traditional folder is a physical directory structure on the hard disk implemented by the housing, and we cannot overload its implementation. The virtual folder is implemented by a COM object extension through the housing, such as a control panel. COM objects must at least be implemented in dynamic connection libraries to implement iUnknown and iShellextinit interfaces. Two main components of the namespace are folder objects and view objects. They implements the ISHELLFOLDER and ISHELLVIEW interfaces, respectively.

Project identifier

Each item displayed on the left of the manager has a unique identifier, because the project is not necessarily a file, so the outer casing can not use the directory to identify them. Windows uses a project identifier to represent them, the structure of the identifier is as follows:

PSHITEMID = ^ TSHITEMID;

TSHITEMID = Packed Record {MKID}

CB: Word; {I need to add the size of the structure}

Abid: array [0..0] of byte;

END;

The identifier is rarely used alone, usually a connection in the identifier symbol chain, indicating the end of the linked list when the CB is 0. When a folder object is created, the housing calls its IPERSISTFolder interface and passes it to one identifier chain list.

Namespace type

The namespace created by the system is called a standard namespace, and the user is called a user-customized namespace. Note that the user-customized namespace only has root node objects to automatically appear in a standard namespace. You can use two ways to create a namespace:

Create a directory in the standard namespace and attach the class identifier to the back of the folder object, expand as the file name of the object. E.g:

{12345678-0000-0000-0000-c00000000000}.

Create the following key value in the registry:

HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows / CurrentVersion /

Explorer / Desktop / Namespace.

The resource manager calls the extended folder object to enumerate its child object, just like a subfolder.

File clip-based object interaction

When the user clicks the " " number of the folder, the manager calls the iShellFolder.EnumObjects function to display the subfolder list. When the user clicks on the lowermost folder, the manager uses the view to display the contents of the object. We have to do two things before:

Create a folder object. The manager first creates the parent object of the selected folder object, then call the ishellfolder.bindtoObject function.

Manager calls the ISHELLFOLDER.CREATEVIEWOBJECT function of the folder object to create a view object.

Folder interaction

There are two types of views: one is a pop-up view window, and the other is that the normal view is displayed on the right of the resource manager. Folder object creation These two views are implemented by calling the ISHELLVIEW.CREATEVIEWWINDOW function of the view object. One thing to note is that a folder object may correspond to multiple view objects because the user may make a lot of windows for a file. This means that the view and folder objects must create a separate COM object for each implementation, and the Explorer will be responsible for synchronizing the content of different views. Create a namespace extension implementation view object using Delphi

Objects must be:

(1) Create a sub-window of a view window and use it to display the contents of the folder.

(2) Communicate with resource manager.

(3) Add a folder related command to the menu bar and toolbar of the resource manager, and process these commands.

(4) Display the upper and lower menu and process drag and drop operations.

Resource Manager To request a view object to be implemented by calling the ISHELLFOLDER.CREATEVIEWOBJECT method of the folder object, the process is:

(1) Folder object Create a new instance of a view and returns an ishellview interface.

(2) Resource Manager Initialization View Objects By calling the ishellview :: CreateViewWindow method. Create a sub-window and return the handle to the resource manager.

(3) View object uses the ISHELLBROWSER interface to customize the toolbar, menu bar, and status bar.

(4) The view displays the contents of the folder in the sub-window.

(5) The view handles the user's input command and toolbar and the menu bar command.

Initialization view object

The parameters of the ishellview.createviewWindow method provide the necessary information to create a sub-window:

(1) The ISHELLVIEW interface pointer of the previous view object can be NIL.

(2) A TFOLDERSETTINGS structure contains the setup information of the previous view, settings.

(3) ISHELLBROWSER interface pointer.

(4) The TRECT structure represents the display range of the view window.

The ishellview.createViewWindow method is called before the previous view is destroyed. Therefore, the ISHELLVIEW interface pointer allows us to communicate with the previous view. If the previous interface belongs to our extension, we can exchange private configuration information with its communication.

A simple way to determine if the ISHELLVIEW pointer belongs to its own extension is to define a private interface. Then call ishellview.queryinterface to request this private interface. If you get the interface, you will explain the interface that is an extended interface. The TFoldersetting structure contains the display setting of the view. The main display mode is a large icon, a small icon, a list, or a detailed information, and there is a flag representing a series of display options, such as whether it is left aligned. We can modify it, the resource manager calls the iShellView.getCurrentInfo method to get the latest information for this structure.

The ISHELLBROWSER interface allows views to communicate with resource manager because there is no other way to get this interface, so the view must be saved to use again. In particular, we need to call ISHELLBROWSER.GETWINDOW to get the parent view window to create a sub-window. After saving the interface pointer, don't forget to call IshellBrowser.AddRef to increase the number of interface references. Use the ishellbrowser.release release interface when you do not need an interface.

Create a sub-window:

(1) Check the TFoldersettings and TRECT structures.

(2) Call the ishellbrowser.getWindow get the parent view window. Create a sub-window and return to the resource manager. Display view: View window always exists, even if no focus is obtained. Therefore, we should maintain the following three states of the sub-window:

1 activation and focus. Set the menu items and tools that correspond to the focus status.

2 activate but no focus. Set the menu items and tools that correspond to the non-focus state.

3 Inactivation state. The view will be destroyed and delete all relevant menu items.

The resource manager notifies the changes in the window status by calling the ishellview.uiactivate method. Instead, the view should also be notified with the IshellBrowser.onviewWindowActive method. When the view is in an active state, we should process window messages such as WM_SIZE, which belongs to the sub-window. It also handles the WM_COMMAND message corresponding to the menu and toolbar. When the view will be destroyed, the resource manager calls the ishellview.destroyviewWindow method notification view.

Implement ISHELLVIEW interface

AddPropertySheetPages method

When the user selects the folder option for the Source Manager, a property page allows the user to modify the folder option. Resource Manager calls ishellview.addpropertySheetPages method Allows the Add Properties page to the property page.

2. GetCurrentInfo method

Before switching the view, the Explorer calls ishellview.getCurrentInfo to request the current TFoldersettings value to pass to the next view.

3. REFRESH method

The resource manager calls ishellview.refresh to refresh the display of the view.

4. SaveViewState method

The resource manager calls the ishellview.saveViewState method prompt view saves its appearance state to restore the status when the view is displayed next time. Returns an ISTREAM interface by calling the ishellbrowser.getViewStateStream method, the view can save the status using this interface.

5. TranslateAcelerator method

When the user presses the shortcut, the Explorer will call the ishellview.translateAccelerator method to pass the message to the view. If the view returns S_FALSE, the resource manager handles this message. If the view processes this message, the view returns S_OK. When the view is focused, the resource manager calls ishellview :: TranslateAccelerator, if the view does not process this message, the resource manager handles it. If the view does not focus, the Explorer will process the message before it is not handled, it will call IshellBrowser.translateAcceleratorsb. Communicate with the resource manager using the ISHELLBROWSER interface.

The ISHELLBROWSER interface is used in the following:

(1) Modify the menu of the Explorer.

(2) Modify the toolbar of the resource manager.

(3) Modify the status bar of the resource manager.

(4) Save the appearance information such as the current setting or status.

Modify the menu of the Explorer

You can use the ISHELLBROWSER interface to modify, add or delete the menu and its associated commands. When each view status changes, the resource manager calls ishellview.uiactivate, so you should put the modification operation here, the basic step is:

(1) Create a menu handle.

Table 2.2

menu

Identification of files FCIDM_MENU_FILEFile edit FCIDM_MENU_EDITFile view FCIDM_MENU_VIEWContainer collection FCIDM_MENU_FAVORITESContainer tool FCIDM_MENU_TOOLSContainer help FCIDM_MENU_HELPWindow (2) call IShellBrowser.InsertMenusSB method, Explorer adds the appropriate menu information.

(3) Modify the returned menu information.

(4) Call the ishellbrowser.set- Menusb method Let the resource manager displays the modified menu.

The resource manager has 6 menus. Resource Manager menu strip is divided into 6 groups: File, Edit, Container, Object, Window, and Help. Table 2.2 lists the identity and packets of each menu.

When calling the iShellBrowser. InsertMenusSB method, a structure that points to ToleMenuGroupWidths must also be passed, and members are initialized to 0. Once you have called the iShellbrowser.IsertmenusSB method, you can use the returned menu handle to perform a normal menu operation.

(1) Add a menu item.

(2) Modify or delete an existing menu item.

(3) Add a new menu.

Note To avoid command conflicts with the resource manager, the resulting command identifier must be between FCIDM_SHVIEWFIRST and FCIDM_SHVIEWLAST. When the resource manager calls the ishellview.uiactivate method to indicate that the view is inactive, you can call the ishellbrowser.remove- MenusSB method to restore the initial state.

Modify toolbar

The step is:

(1) Add button's bitmap to the list of objects.

(2) Define the display string of the button.

(3) Add button to the toolbar.

Call the ishellbrowser.sendControlMSG method Send TB_ADDBITMAP messages to the toolbar. Set the parameter ID to FCW_TOOLBAR, set WPARAM as the number of buttons in the bitmap, and LParam is the address of the TTBAddBitmap structure. The image index returns in the PRET parameter.

There are two ways to set the button display string:

(1) Set the istring member of the TTBButton structure.

(2) Call the ishellbrowser.sendControlmsg Send TB_ADDString message. The WPARAM parameter is 0, and the LPARAM parameter points to the string. The string index is returned by the PRET.

Add a button, you must first fill in the TTBButton structure and then call ISHELLBROWSER. SETTOOLBARITEMS.

Modify the resource manager status

Two methods are:

(1) Use the ishellbrowser.setStatusTextSb method to display the string.

(2) Send a message directly with the ishellbrowser.sendControlmsg method.

Implement folder interface

Registration extension

The following key values ​​are only meaningful for the namespace containing the namespace containing the subdirectories, and these values ​​cannot be used for those subdirectory being an extension of the file system directory. To change the extended behavior of a subdirectory, you should add the following key value to the extended CLSID sub-key:

WantsforParsing: The extension of the subdirectory usually has the following form: {guid}. This extension typically includes a virtual sub-object. However, some extensions, such as my document, is completely corresponding to the file system directory. If our extension is just redefined and expansion of existing system folders, you can set the WantsforParsing value. The resource manager will request root directory object resolution name by calling the ISHELLFOLDER.GETDISPLAYNAMEOF method of the root target object. Uflags will be set to SHGDN_FORPARSING, while the PIDL parameter is set to a empty PIDL containing only one end. Hidefolderverbs: Verbs defined under HKEY_CLASSES_ROOT / FOLDER sub-keys are usually associated with all extensions. They appear in the extended context-related menu and can be called via Shellexecute, and if you want to prohibit these Verbs to associate with our extension, you need to set the HidefolderverBS value.

HideasDelete: If a user tries to delete our extension, the Explorer will hide this extension.

HideasDeleteperUser: This value has the same effect as Hideasdelete, but it is based on a single user, and the extension will only be hidden to the extension of the extended user, but still display other users.

QueryForoverLay: Set this value to indicate the root of the root to have a mask overlapping icon. At the same time, this requires that the folder object must support the ISHELLICONOVERLAY interface. Before the resource manager displays the icon of the root directory, it requests an overlap icon by calling two ways to call the iShelliconoverLay interface.

Below these key values ​​apply to all namespace extensions:

(1) To specify the display name of the extended node folder, set the extended CLSID subkey default value as the name string.

(2) When the cursor is parked on a folder, a leap information prompt should be displayed to describe the contents of the folder. If you want to provide a leap information prompt for the scaled root directory, create a string type Infotip value under the scaled CLSID sub-keys, and assign the value to the information string you want to display.

(3) If you want to specify a custom icon for the extended root directory, create a defaulton subkey under the extended CLSID sub-key. Set the default value of the defaulton subkey is a string containing the file name of the icon, and the string should also be separated from the index value in the file to the file (at 0) in the string.

(4) When the default, the context-related menu corresponding to the expanded root directory will include the menu item defined under the HKEY_CLASES_ ROOT / FOLDER key. At the same time, the outer casing also determines whether to add deletion, rename, and attribute menu items based on the extended SFGAO_XXX flag. If you want to add or overload the already menu item in the menu, just as the context-related menu of the extended file class, you need to create a shell subkey under the extended CLSID sub-key and define the corresponding command. Extending context menus.

(5) If a more flexible custom root directory is required, a context-related menu extension can be implemented. To register this menu extension, you need to create a shellex subkey under the extended CLSID sub-key and register the menu extension or the SHELL EXTENSION HANDLER.

(6) If you want to add a new property page on the properties page that is called with the properties of the extension, you need to add a new property page, you need to implement a property page extension while setting the SFGAO_HASPROPSHEET property of the folder. And the same registration property page extension is the same as the context related menu. (7) To specify the properties of the root directory, you need to add the shellfolder subkey under the extended CLSID sub-key and create an Attributes value to set it into a combination of the appropriate SFGAO_xxx identity.

Table 2.3 is some commonly used attribute identifiers:

Table 2.3

Attribute Identifier Sold SFGAO_FOLDER0X20000000 Extension root directory includes one or more items SFGAO_HASSUBFOLDER0X80000000 Extended root directory consisting of one or more subdirectories SFGAO_CANDELETE0X00000020 The expansion directory can be deleted by the user. Context-sensitive menu to delete a directory menu item This flag should be set for junction points that are placed under one of the virtual foldersSFGAO_CANRENAME0x00000010 extension root directory can be renamed SFGAO_HASPROPSHEET0x00000040 root directory attributes page, but must implement a property page extension

The following example shows how to register a namespace extension:

HKEY_CLASSES_ROOT

CLSID

{EXTENSION CLSID} = DEMO

Infotip = presentation

InprocServer32 = C: /Namespace/demo.dll

ThreadingModel = Apartment

Shellfolder

Attributes = 0xa00000020

// Attributes include sfgao_folder, sfgaohassubfolder, sfgao_candelete flag

Defaulton = C: /Namespace/demo.dll, 1

2. Handling PIDL

Each namespace must have a unique identifier PIDL.

Note: The most important aspect of designing a data structure for PIDL is to ensure that the structure is sustainable and transmitted, and the meaning is:

(1) Sustainability: The system often makes the PIDL for long-term storage, such as in the shortcut file. After a while, naturally need to recover PIDL from storage, and PIDL recovered from storage must be effective for our extension. This means that the pointer or handle cannot be used in the PIDL structure. This type of data is usually always changed.

(2) Transmissionability: When a PIDL is transferred from one machine to another machine, it is still necessary to make it meaningful. For example, a PIDL can be written to a shortcut file, copy it into a floppy disk, and then install it to another machine, if our extension is installed on this machine, then the copied shortcut file should continue to be valid. To make PIDL can be transmitted, an ANSI or Unicode string should be used in PIDL, and also pay attention to the PIDL established at a Unicode version will not be read by the ANSI version.

Here is a simple PIDL data structure design:

Type

TPIDLDEMP = Record

CB: Integer;

DWTYPE: DWORD;

WszdisplayName: array [0..39] of char;

END;

The CB parameter is used to specify the size of the data structure, which ensures that the TPIDLDEMO structure is a valid SHITEMID structure. The remaining part of the structure is equivalent to the Abid parameter in the SHITEMID structure, which is used to save private data. The DWTYPE parameter is an extension defined variable to indicate the type of the shell object, for example, if the DWTYPE is true, can be used to represent a folder, and use false to represent other housing objects. WSZDisPlayName is used to save the display name of the housing object. Note that the same name cannot be given to different objects in the catalog, and because of the different names, WSZDisplayName can be used as an object ID. Here, the WSZDisPlayName length is set to 40 to ensure that the Shitemid structure is double word alignment. In order to limit the size of the PIDL, we can certainly use the growing character array, you must be aligned, you can only have enough '/ 0' characters to add enough '/ 0' characters after the display string. In addition, other custom parameters such as object dimensions, attributes, and other custom parameters can be included in the structure. Implement basic interface

IPersistFolder interface

The IPersistFolder.initialize method needs to provide a qualified PIDL to the new object. We may need to store PIDL to use this PIDL to create a qualified PIDL for its sub-objects for future use. Folder objects can also call iPersistFolder.getClassID to request object class identifiers. Typically, the creation and initialization of the folder object is implemented by the ISHELLFOLDER.BINDTOOBJECT method of the parent directory. When a user browses our extension, the resource browser creates and initializes the extended root directory object. The root directory object should include the PIDL obtained from the desktop to the extended part of the IPersistFolder.Initialize method so that our extension can be constructed. PIDL.

2. Ishellfolder interface

The resource manager can obtain our extended CLSID through a variety of ways. After getting CLSID, the resource manager uses CLSID to create and initialize an instance of the root directory object and query the ISHELLFOLDER interface. Our extension This time you need to create an root directory object and return to the ISHELLFOLDER interface of the object. The resource manager depends on the ISHELLFOLDER interface with the extended interaction. Resource Manager uses iShellfolder to use:

(1) Request an object to enumerate the contents of the root directory.

(2) Various information for obtaining the contents of the root directory.

(3) Request additional options that can be used to get additional information, such as icons or right monsters.

(4) Request a directory object representing a subfolder of the root folder.

ISHELLFOLDER interface method

ENUMOBJECTS method

The resource manager determines the contents included in the folder by calling the iShellFolder.enumObjects method. This method creates a standard enumeration object to provide the IenumIdList interface. The IenumidList interface enables the resource manager to get the PIDL of all objects included in the folder, and the PIDL can then be used to get information for these objects.

Note The IenumIdlist.next method should return PIDL relative to the parent directory. PIDL should only contain the TSHITEMID structure of the object and have a end.

2. CREATEVIEWOBJECT method

Resource Manager calls the CreateViewObject method to get the ISHELLVIEW interface, this interface is used to manage views. CreateViewObject can also be used to get optional interfaces such as IconTextMenu. If the resource manager wants to get an optional interface of the object under the directory, you need to call the iShellFolder.getuiObjectof method.

3. GetuiObjectof method

The Resource Manager getuiObjectof method obtains additional information of the object, such as icon and right-click menu.

4. BindtoObject method

The BindToObject method is called when the user opens the extended subdirectory. If the parameter riid = IID_ID_IDFOLDER, you should create and initialize a subdirectory folder object and return an ishellfolder interface. 5. GetDisplayNameOf method

The getDisplayNameOF method is used to convert PIDL to become a displayed name string. PIDL must be relative to the parent directory of the object. In other words, it must contain a non-empty SHITEMID structure. Because there are a variety of named objects, the Explorer represents the name type by defining a combination of SHGNO identifiers in a UFLAGS parameter. SHGDN_NORMAL or SHGDN_INFOLDER will be used to specify the name relative to the folder or relative to the desktop. The other three values ​​SHGDN_FOREDITING, SHGDN_FORADDRESSBAR and SHGDN_FORPARSING can be used to specify the use of the name.

The name must be returned in the form of Strret, if Shgdn_ForedIting, SHGDN_FORADDRESSBAR and SHGDN_FORPARSING are not set, return to the display name of the housing object. If you set the SHGDN_FORPARSING ID, the resource manager requests a parsing name, the parsing name can be called by the iShellFolder.ParsedisplayName method to obtain the object's PIDL, even if the object is in the current directory in the current directory in the current directory. 1 or more layers. For example, for a file object, its parsing name is its path, we use the full path name of the file system object to call the ParsedInsPlayName method of the desktop's ISHELLFOLDER interface, which will return the full PIDL of this object.

Because the resolution name is a text string, it is not necessary to include the display name. The designs of the parsed name can be based on making the iShellFolder.ParsedisPlayName method calls more efficient. For example, many housing virtual folders are not part of the file system, and there is no complete path name. Each parser name of each folder is usually combined with a GUID and analytical name. The format is as follows:

:: {Guid}

6. GetAttributeSof method

The resource manager calls the iShellFolder.GetaTributeSof method to determine the properties of the item under the folder, the parameter CIDL gives the number of items being queried, and the parameter apidl points to the corresponding PIDL linked list.

Because some attributes are very time consuming, the resource manager usually limits the range of queries by setting the RFGINOUT parameter, and only those identifiers define the properties in the RFGINOUT parameter.

Note: The properties of the housing object must be set correctly to display correctly. For example, if a folder includes subdirectories, you must set the sfgao_hassubfolders ID. At this time, the resource manager adds a number icon before the folder icon in the tree view.

7. ParsedisPlayName method

The ishellfolder.parsedisplayName method is equivalent to the inverse operation of the ISHELLFOLDER. GetDisplayNameOF method. It is mainly used to transform the parsing of the housing object called the associated PIDL. The returned PIDL is a folder relative to the exposed interface. To get a full PIDL, the caller also needs to attach this PIDL behind the PIDL of the exposed interface folder.

The ishellfolder.parsedisplayName method can also be used to request the properties of the shell object, as we determine that all properties are very consuming, we also need to limit the information of interest by setting the SFGAO_xxx identity.

IenumidList interface

When the resource manager needs to enumerate the enclosure object included in the folder, it calls the ishellfolder. Enumjects method, the folder object must create an enumeration object to expose the IEnumIDList interface and return the interface pointer.

IEnumidList is a standard OLE enumeration interface that is easy to implement, but to note that the returned PIDL must be relative to the folder and only one ShItemid structure and terminator. Implement other optional interfaces

In addition to the basic interfaces above, there is also a number of optional housing interfaces, such as the SUCH AS IExTrActCon interface can be used to customize the icon of the view, and, for example, the iDataObject interface can be used to support drag and drop characteristics.

The above interface is not directly exposed by the folder object, but the resource manager requests by calling the following two ISHELLFOLDER methods:

The resource manager calls the ISHELLFOLDER.GetuiObjectof method of the folder object to request the interface of the object containing the folder.

The resource manager requests the interface of the folder itself by calling the ISHELLFOLDER.CREATEVIEWOBJECT method of the folder object.

The most common optional interface will be discussed below:

IEXTRACTICON interface

The resource manager requests an IEXTRACTICON interface before it displays the folder content. This interface allows the icon for the object contained in the custom folder, otherwise the standard file and folder icon will be used. Refer to the specific details of the IEXTRACTICON interface to see MSDN.

2. IconTextMenu interface

When the user clicks the right button on the housing object, the Explorer requests the IconTextMenu interface to extend the details of the IconTextMenu interface to see MSDN.

3. iQueryInfo interface

The resource manager calls the iQueryInfo interface to get the information leap prompt string, see MSDN.

4. IdataObject and IDROPTARGET interface

For extended methods, there is no direct method to know if the user performs deletion, copy, or dragging and dropping an object in the resource manager. However, whenever there is such an operation, the resource manager will request an iDataObject interface. To allow object operations, create a data object and return its IDATAOBJECT interface pointer.

When the user tries to release a data object to the enclosure object in the extended housing object, the resource manager will request an IDROPTARGET interface. To allow the data object to be released, you need to create an object to expose the IDROPTARGET interface and return the interface pointer. Specific implementations can be found in the previous discussion about COM-based drag and drop technologies.

Name Space Extended Two Main Components are folder objects and view COM objects, where folder objects are to implement iUnknown, ishellextinit, ISHELLFOLDER, and IPERSISTFolder interfaces. The view object is at least to implement iUnknown, ishellextinit, and the ISHELLVIEW interface. After the folder object is created, the housing will notify it in the namespace through the IPersistFolder interface, that is, its item identifier list.

Folder object interaction with sub-shell objects

After adding a namespace extension to the system, the user can control the content displayed in the extension. Or expand the folders in the left panel, or some inventory, the resource manager displays the sub-objects included in the right display panel.

When you double-click the folder object after the " " font number of the file clip object, the behavior of the resource manager standard is the subdirector of the selected folder. This is achieved by calling the EnumiTS method of the ISHELLFOLDER interface of the folder object. When the user clicks on the folder, the Explorer will display the view of the object contained in the folder, and the extension must do two things before the display view:

Create a folder object and call the Bindtoobject method of the object's ISHELLDER interface to bind.

Create a view object. Once the resource manager creates a folder object, it will call the CreateViewObject method for the ISHELLFOLDER interface of the object.

Folder object interact with the same view

Figure 2.5

Once the view object is created, you must determine the created view type. One is a pop-up window for displaying the outer casing object item in the folder. Such views can be called from the open commands of the folder right mole menu, as shown in Figure 2.5.

The other is that when the user doubles the folder of the left panel, the content is displayed in the right panel when the content is default. Folder Object Creating View Window is implemented by calling the CreateViewWindow method of the ISHELLVIEW interface of the view object. View objects must implement the CREATEVIEWINDOW method to determine which type of view created.

It is also important to pay attention to a folder object, and there are multiple view objects in the system, which can open any multiple resource manager and view window. Therefore, the views and folder objects must be implemented as an independent COM object. As for the display content of synchronous different view windows, the resource manager is responsible for processing.

Next, you will have a very simple extension on how to implement it, and we will create a very simple extension, which is the content of all types of files in the view. The following is an explanation of each unit in the example project:

Shellfolder.Pas: implements a folder object.

Shellview.Pas: A view object is implemented.

ViewForm.PAS: The form that is displayed in the right panel is implemented.

Below is the specific implementation code of the folder COM object:

Unit shellfolder;

Interface

Uses Windows, ActiveX, Comobj, Comserv, Shlobj, ShellView;

Const

CLSID_RADFINDBROWSER: Tguid = '{23CE4E06-73A7-11D0-BC62-00A0243ABE0B}';

Type

TshellFolderImpl = Class (Tcomobject, IshellFolder, IPersistFolder)

protected

Function IPersistFolder.initialize = IPERSISTFOLDER_INITIALIZE;

public

// ishellfolder

Function ParsedisplayName (Hwndowner: hwnd;

PBCRESERVED: POINTER; LPSZDISPLAYNAME: POLESTR; OUT PCHEAN: ULONG;

OUT PPIDL: PitemidList; VAR DWATTRIBUTES: ULONG): HRESULT; STDCALL;

Function EnumiCTS (HWndowner: hwnd; grfflags: dword;

Out enumidlist: inumidlist: hResult; stdcall;

Function BindtoObject (PIDL: PitemidList; PBCRESERVED: POINTER;

Const riid: tiid; out ppvout: hResult; stdcall;

Function BindtoStoRage (PIDL: PitemidList; PBCRESERVED: POINTER;

Const riid: tiid; out ppvobj): hResult; stdcall;

Function CompareIDs (LPARAM: LPARAM;

PIDL1, PIDL2: PITEMIDLIST: HRESULT; STDCALL;

Function CreateViewObject (hwndowner: hwnd; const riid: tiid;

OUT PPVOUT: hResult; stdcall;

Function GetAttributesof (CIDL: UINT; VAR APIDL: PitemidList;

Var RGFINOUT: UINT): HRESULT; stdcall; function getuiobjectof (hwndowner: hwnd; cidl: uint; var apidl: pitemidlist;

Const riid: tiid; prgfinout: Pointer; OUT PPVOUT: HRESULT; stdcall;

Function getDisplayNameOf (PIDL: PitemidList; UFLAGS: DWORD;

Var lpname: TSTRRRET: HRESULT; stdcall;

Function setNameof (Hwndowner: hwnd; pidl: pitemidlist; lpszname: polestr;

UFLAGS: DWORD; VAR PPIDLOUT: PITEMIDLIST: HRESULT; STDCALL;

// ipersist

Function GetClassID (Out ClassID: Tclsid): hResult; stdcall;

// ipersistfolder

Function IPersistFolder_Initialize (PIDL: PitemidList): HRESULT; Virtual

STDCALL;

END;

IMPLEMENTATION

Uses

Registerextension;

Function TshellFolderImpl.ParsedisplayName (Hwndowner: hwnd;

PBCRESERVED: POINTER; LPSZDISPLAYNAME: POLESTR; OUT PCHEAN: ULONG;

OUT PPIDL: PitemidList; var dwattributes: ulong): HRESULT;

Begin

Messagebox (0, 'tshellfolderimpl.parsedisplayName', NIL, 0);

Result: = E_NOTIMPL;

END;

Function TshellFolderImpl.enumObjects (Hwndowner: hwnd; grfflags: dword;

Out enumidlist: ienumidlist): HRESULT;

Begin

Messagebox (0, 'TshellFolderimpl.enumObjects', NIL, 0);

Result: = E_NOTIMPL;

END;

Function TshellfolderImpl.CompareID (LPARAM: LPAR)

PIDL1, PIDL2: PitemidList: hResult;

Begin

Messagebox (0, 'TshellFolderImpl.comPareIDS', NIL, 0);

Result: = E_NOTIMPL;

END;

Function TshellfolderImpl.gettributesof (CIDL: UINT; VAR APIDL: PitemidList;

Var RGFINOUT: UINT): HRESULT;

Begin

Messagebox (0, 'TshellFolderimpl.getattributesof', nil, 0);

Result: = E_NOTIMPL;

END;

Function TshellFolderImpl.getdisplayNameOf (PIDL: PitemidList; UFLAGS: DWORD;

Var lpname: tstrret; hRESULT;

Begin

Messagebox (0, 'tshellfolderimpl.getdisplayNameOf', nil, 0); Result: = E_NOTIMPL;

END;

Function TshellFolderImpl.setNameOf (Hwndowner: hwnd; pidl: pitemidlist;

LPSZNAME: POLESTR;

UFLAGS: DWORD; VAR PPIDLOUT: PITEMIDLIST: HRESULT

Begin

Messagebox (0, 'tshellfolderimpl.setnameof', nil, 0);

Result: = E_NOTIMPL;

END;

{IPERSISTFOLDER}

Function TshellFolderImpl.getClassID (Out ClassID: Tclsid): HRESULT

Begin

ClassID: = CLSID_RADFindBrowser;

Messagebox (0, 'TshellfolderImpl.getClassID', NIL, 0);

Result: = noerror;

END;

Function TshellFolderImpl.iPersistFolder_initialize (PIDL: PitemidList): HRESULT

Begin

Result: = noerror;

END;

Function TshellfolderImpl.BindToObject (PIDL: PitemidList;

PBCRESERVED: POINTER; Const Riid: TiID; OUT PPVOUT: HRESULT

Begin

Messagebox (0, 'TshellFolderImpl.BindToobject', NIL, 0);

Result: = E_NOTIMPL;

END;

Function TshellFolderImpl.BindtOStorage (PIDL: PitemidList;

PBCReServed: Pointer; Const Riid: Tiid; Out PPVOBJ): HRESULT;

Begin

Messagebox (0, 'TshellfolderImpl.bindtostorage', NIL, 0);

Result: = E_NOTIMPL;

END;

// When the IPERSISTFolder.Initialize method is called, the housing will call this method, we must build a new window to display view objects.

Function TshellFolderImpl.createViewObject (hwndowner: hwnd;

Const riid: tiid; out ppvout: hResult;

VAR

ShellView: ishellview;

Begin

Try

IF ISEqualguid (RIID, ISHELLVIEW) THEN

Begin

Shellview: = TshellViewImpl.create;

Result: = (ShellView as iUnknown) .queryinterface (RIID, PPVOUT)

end

Else

Result: = E_NOINTERFACE;

Except

ON E: EOLESYSERROR DO

Result: = E. HerrorCode;

Else

Result: = E_UNEXPECTED;

END;

END;

Function TshellfolderImpl.getuiObjectof (Hwndowner: hwnd; cidl: uint)

VAR APIDL: PitemidList; Const Riid: TiID; prgfinout: Pointer; OUT PPVOUT: HRESULT

Begin

Messagebox (0, 'TshellFolderImpl.getuiObjectof', NIL, 0);

Result: = E_NOTIMPL;

END;

INITIALIZATION

TNamespaceExtensionFactory.create (Comserver, TshellFolderImpl,

CLSID_RADFINDBROWSER,

',' Delphi Radfind Explorer Extension ', CIMULTIINSTANCE

End.

In the above code, there is no implementation for most of the iShellfolder interface, just give an empty implementation like this:

Function TshellFolderImpl.BindtOStorage (PIDL: PitemidList;

PBCReServed: Pointer; Const Riid: Tiid; Out PPVOBJ): HRESULT;

Begin

Messagebox (0, 'TshellfolderImpl.bindtostorage', NIL, 0);

Result: = E_NOTIMPL; // Nothing to implement this method

END;

But we must implement an important way, this is the CreateViewObject method, in this method, first create an instance of the view object, and then return the interface requested by the resource manager. The process is very simple, you can implement only the 5 lines of code below:

IF ISEqualguid (RIID, ISHELLVIEW) THEN

Begin

Shellview: = TshellViewImpl.create; // Creating a view object instance Returns the requested interface

Result: = (Shellview As IUnknown) .queryinterface (RIID, PPVOUT),

End

In addition to this, you can also achieve the same functionality as the above code. The code is implemented as follows:

// Get the class factory

Factory: = COMCLASSMANAGER.GETFACTORYFROMCLASSID (CLSID_RADFINDVIEW);

IF factory <> nil dam

Begin

FObject: = Factory.createComobject (nil);

IF FOBJECT <> NIL THEN

Begin

// Request the interface

FOBJECT.OBJADDREF;

Result: = FOBJECT.OBJQUERYINTERFACE (RIID, PPVOUT);

FOBJECT.OBJRELEASE;

END;

Unit shellview;

Interface

Uses Windows, ActiveX, CommCtrl, Shellapi, Shlobj, ViewForm;

Type

TshellviewImpl = Class (TinterFaceDObject, ISHELLVIEW)

Private

Ffoldersettings: tfoldersettings;

Fshellbrowser: ishellbrowser;

FHWNDPARENT: HWND;

FFORM: TVIEW;

public

Constructor crete;

// IoleWindow Methods

Function getWindow (Out Wnd: hwnd): hResult; stdcall;

Function ContextSensitiveHelp: hResult; stdcall; // ishellview methods

Function TranslateAccelerator (VAR MSG: TMSG): hResult; stdcall;

Function EnableModeless (Enable: Boolean): HRESULT; stdcall;

Function UIActivate (state: uint): hResult; stdcall;

Function refresh: hResult; stdcall;

Function CreateViewWindow (Prevview: ishellview;

Var foldersettings: tfoldersettings; shellbrowser: ishellbrowser;

Var Rect: TRECT; OUT WND: HWND): HRESULT; STDCALL;

Function DestroyViewWindow: HRESULT; stdcall;

Function GetCurrentInfo (Out Foldersettings: TFoldersettings): HRESULT;

STDCALL;

Function AddPropertySheetPages (Reseved: DWORD;

Var lpfnaddpage: tfnaddpropsheetpage; lparam: lparam): hResult; stdcall;

Function SaveViewState: HRESULT; stdcall;

Function SelectItem (PIDL: PitemidList; Flags: UINT): HRESULT; stdcall;

Function GetItemObject (item: uint; const sameile: tiid; var iptr: Pointer):

HRESULT; STDCALL;

Property shellbrowser: ishellbrowser read fshellbrowser;

END;

IMPLEMENTATION

Uses

Registerextension, classes;

Constructor tshellviewImpl.create;

Begin

Inherited Create;

FFORM: = NIL;

Fshellbrowser: = NIL;

END;

// IoleWindow Implementation

Function TshellviewImpl.GetWindow (Out Wnd: HWnd): hResult; stdcall;

Begin

Fshellbrowser.SetStatustextSb (StringToolestr ('IoleWindow.GetWindow');

Wnd: = fform.handle;

Result: = noerror;

END;

Function TshellviewImpl.ContextSensitiveHelp (fentermode: bool): HRESULT

STDCALL;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('IoleWindow.ContextSensitiveHelp');

Result: = E_NOTIMPL;

END;

// IshellView Implementation

Function TshellviewImpl.TranslateAccelerator (VAR MSG: TMSG): hResult; stdcall;

Begin

Result: = E_NOTIMPL; END;

Function TshellviewImpl.EnableModeless (Enable: Boolean): HRESULT; stdcall;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.enablemodeless);

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.uiactivate (state: uint): hResult; stdcall;

VAR

String;

Begin

Case Tsvuiaenums (State) of

Svuia_Deactivate:

S: = 'deactivate view';

Svuia_Activate_nofocus:

S: = 'Activate View without Focus';

Svuia_Activate_FOCUS:

S: = 'Activate View with focus';

Svuia_inplaceActivate:

S: = 'Activate View for Inplay-Activation With Inlinex Control';

END;

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.uiactivate:' s);

Result: = noerror;

END;

Function TshellviewImpl.refresh: hResult; stdcall;

Begin

FshellBrowser.SetStatusTextSb (StringToolestr ('ishellview.refresh);

Result: = E_NOTIMPL;

END;

Function TshellViewImpl.createViewWindow (Prevview: ishellview;

Var foldersettings: tfoldersettings; shellbrowser: ishellbrowser;

Var Rect: TRECT; OUT WND: HWND): HRESULT; STDCALL;

Begin

FFoldersettings: = foldersetting;

Fshellbrowser: = shellbrowser;

Fshellbrowser.getWindow (fHWndparent);

Try

Fform: = TView.createshview (nil, fshellbrowser, self as ishellview);

Wnd: = fform.handle;

SetParent (WND, FHWNDPARENT);

With fform do

Begin

Setwindowpos (Handle, Hwnd_top, Rect.left, Rect.top,

Rect.right - Rect.Lep, Rect.bottom - Rect.top, SWP_SHOWINDOW;

SHOW;

END;

IF WND <> 0 THEN

Result: = noerror

Else

Result: = E_UNEXPECTED;

Except

Result: = E_UNEXPECTED;

END;

END;

Function TshellviewImpl.destroyViewWindow: HRESULT; stdcall;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.destroyViewin-dow'); fform.free;

FFORM: = NIL;

Result: = noerror;

END;

Function TshellviewImpl.getCurrentInfo (Out Foldersettings: TFoldersettings):

HRESULT; STDCALL;

Begin

Fshellbrowser.SetStatustextsb (StringToolestr ('ishellview.getcurrent-info');

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.saveViewState: hResult; stdcall;

Begin

Fshellbrowser.setStatustextSb (StringToolestr ('ishellview.saveViewState');

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.selectItem (PIDL: PitemidList; Flags: uint): hResult;

STDCALL;

Begin

FshellBrowser.SetStatustextSb (StringToolestr ('ishellview.selectItem');

Result: = E_NOTIMPL;

END;

Function TshellViewImpl.addpropertySheetPages (Reseved: DWORD;

Var lpfnaddpage: tfnaddpropsheetpage; lparam: lparam): HRESULT;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.addpropertySheetpages');

Result: = E_NOTIMPL;

END;

Function TshellViewImpl.getItemObject (item: uint; const iid: tiid;

Var iptr: Pointer: hResult;

Begin

Fshellbrowser.SetStatustextsb (StringToolestr ('ishellview.getItemObject');

Result: = E_NOTIMPL;

END;

End.

Next is the implementation code of the view object:

Unit shellview;

Interface

Uses Windows, ActiveX, CommCtrl, Shellapi, Shlobj, ViewForm;

Type

TshellviewImpl = Class (TinterFaceDObject, ISHELLVIEW)

Private

Ffoldersettings: tfoldersettings;

Fshellbrowser: ishellbrowser;

FHWNDPARENT: HWND;

FFORM: TVIEW;

public

Constructor crete;

// IoleWindow Methods

Function getWindow (Out Wnd: hwnd): hResult; stdcall;

Function ContextSensitiveHelp: hResult; stdcall;

// Ishellview Methods

Function TranslateAccelerator (var Msg: TMSG): hResult; stdcall; function enablemodeless (enable: boolean): hResult; stdcall;

Function UIActivate (state: uint): hResult; stdcall;

Function refresh: hResult; stdcall;

Function CreateViewWindow (Prevview: ishellview;

Var foldersettings: tfoldersettings; shellbrowser: ishellbrowser;

Var Rect: TRECT; OUT WND: HWND): HRESULT; STDCALL;

Function DestroyViewWindow: HRESULT; stdcall;

Function GetCurrentInfo (Out Foldersettings: TFoldersettings): HRESULT;

STDCALL;

Function AddPropertySheetPages (Reseved: DWORD;

Var lpfnaddpage: tfnaddpropsheetpage; lparam: lparam): hResult; stdcall;

Function SaveViewState: HRESULT; stdcall;

Function SelectItem (PIDL: PitemidList; Flags: UINT): HRESULT; stdcall;

Function GetItemObject (item: uint; const sameile: tiid; var iptr: Pointer):

HRESULT; STDCALL;

Property shellbrowser: ishellbrowser read fshellbrowser;

END;

IMPLEMENTATION

Uses

Registerextension, classes;

Constructor tshellviewImpl.create;

Begin

Inherited Create;

FFORM: = NIL;

Fshellbrowser: = NIL;

END;

// IoleWindow Implementation

Function TshellviewImpl.GetWindow (Out Wnd: HWnd): hResult; stdcall;

Begin

Fshellbrowser.SetStatustextSb (StringToolestr ('IoleWindow.GetWindow');

Wnd: = fform.handle;

Result: = noerror;

END;

Function TshellviewImpl.ContextSensitiveHelp (fentermode: bool): HRESULT

STDCALL;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('IoleWindow.ContextSensitiveHelp');

Result: = E_NOTIMPL;

END;

// IshellView Implementation

Function TshellviewImpl.TranslateAccelerator (VAR MSG: TMSG): hResult; stdcall;

Begin

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.EnableModeless (Enable: Boolean): HRESULT; stdcall;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.enablemodeless);

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.uiactivate (state: uint): hResult; stdcall;

VAR

String;

Begin

Case Tsvuiaenums (State) of

Svuia_Deactivate:

S: = 'View Focus';

Svuia_Activate_nofocus:

S: = 'activation view, no focus';

Svuia_Activate_FOCUS:

S: = 'activation view is focused';

Svuia_inplaceActivate:

S: = 'The original ActiveX activation' of the activation view;

END;

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.uiactivate:' s);

Result: = noerror;

END;

Function TshellviewImpl.refresh: hResult; stdcall;

Begin

FshellBrowser.SetStatusTextSb (StringToolestr ('ishellview.refresh);

Result: = E_NOTIMPL;

END;

// Once TshellViewImpl is created, this function will be called to create a real view window.

Function TshellViewImpl.createViewWindow (Prevview: ishellview;

Var foldersettings: tfoldersettings; shellbrowser: ishellbrowser;

Var Rect: TRECT; OUT WND: HWND): HRESULT; STDCALL;

Begin

// Save folder settings

FFoldersettings: = foldersetting;

Fshellbrowser: = shellbrowser;

// Get the resource manager parent window handle

Fshellbrowser.getWindow (fHWndparent);

// Create a form, pass the folder and view object interface to the form

Notifying the shell form When getting focus

Try

Fform: = TView.createshview (nil, fshellbrowser, self as ishellview);

Wnd: = fform.handle;

SetParent (WND, FHWNDPARENT);

With fform do

Begin

Setwindowpos (Handle, Hwnd_top, Rect.left, Rect.top,

Rect.right - Rect.Lep, Rect.bottom - Rect.top, SWP_SHOWINDOW;

SHOW;

END;

IF WND <> 0 THEN

Result: = noerror

Else

Result: = E_UNEXPECTED;

Except

Result: = E_UNEXPECTED;

END;

END;

Function TshellviewImpl.destroyViewWindow: HRESULT; stdcall;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.destroyViewin-dow'); fform.free;

FFORM: = NIL;

Result: = noerror;

END;

Function TshellviewImpl.getCurrentInfo (Out Foldersettings: TFoldersettings):

HRESULT; STDCALL;

Begin

// Display information in the status bar

FshellBrowser.SetStatusTextSB (StringToolestr ('ishellview.getcurrentInfo');

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.saveViewState: hResult; stdcall;

Begin

Fshellbrowser.setStatustextSb (StringToolestr ('ishellview.saveViewState');

Result: = E_NOTIMPL;

END;

Function TshellviewImpl.selectItem (PIDL: PitemidList; Flags: uint): hResult;

STDCALL;

Begin

FshellBrowser.SetStatustextSb (StringToolestr ('ishellview.selectItem');

Result: = E_NOTIMPL;

END;

Function TshellViewImpl.addpropertySheetPages (Reseved: DWORD;

Var lpfnaddpage: tfnaddpropsheetpage; lparam: lparam): HRESULT;

Begin

FshellBrowser.SetStatustextsb (StringToolestr ('ishellview.addpropertySheetpages');

Result: = E_NOTIMPL;

END;

Function TshellViewImpl.getItemObject (item: uint; const iid: tiid;

Var iptr: Pointer: hResult;

Begin

Fshellbrowser.SetStatustextsb (StringToolestr ('ishellview.getItemObject');

Result: = E_NOTIMPL;

END;

End.

Similar to the implementation of the folder, only the CreateViewWindow method for the ISHELLVIEW interface is simple. This method is simple. The only thing to say is that the following code is set to the subsidiary of the resource manager in the method, so that resources The manager can refresh and redefine the size of the form.

Wnd: = fform.handle;

SetParent (WND, FHWNDPARENT);

Our form features to display the system logs when starting to start, and can display any other files in Richedit, and implement the code as follows, the important part has added a note:

Constructor TView.create (Aowner: Tcomponent);

Begin

ShowMessage ('Should use CreateshView to create view object');

Abort; // Quiet exception

END;

(For the form, it must be a sub-form)

Constructor TView.createshview (Aowner: Tcomponent; shbrowser: ishellbrowser; shview: ishellview); Begin

FshBrowser: = NIL;

Fshellview: = nil;

Inherited Create (Aowner);

Fshbrowser: = shbrowser;

Fshellview: = shview;

// increase the reference count

Fshbrowser._addref;

Fshellview._addref;

Setwindowlong (Handle, GWL_Style, WS_CHILD); / / must be a child form

END;

DESTRUCTOR TVIEW.DESTROY;

Begin

Try

IF assigned (fshbrowser) THEN

Fshbrowser._release; // Reduce the reference count

IF assigned (fshellview) THEN

Fshellview._release;

Finally

Inherited destroy;

end

END;

(Open other files)

Procedure TView.n1click (sender: TOBJECT);

Begin

IF openDialog1.execute the

Richedit1.Lines.LoadFromFile (OpenDialog1.FileName);

END;

(We must call the ONVIEWINDOWACTIVE callback function when you get the focus

In order to call the uiactivate interface callback)

Procedure TView.MMActivate (Sender: TOBJECT);

Begin

FshBrowser.onviewWindowActive (fshellview);

Richedit1.setfocus;

END;

(Loading System Log Text)

Procedure TView.FormShow (Sender: TOBJECT);

Begin

IF fileexists ('c: /bootlog.txt') THEN

Richedit1.lines.LoadFromfile ('c: /bootlog.txt')

Else

IF fileexists ('c: /config.sys') THEN

Richedit1.lines.LoadFromfile ('c: /config.sys')

Else

Richedit1.Lines.Add ('bootlog.txt or config.sys not found ")

END;

End.

Finally, the registration is a good extension. Here is the current code. Here is the annotation of the code. The meaning of the specific process will see the previous narrative:

Unit registerextension;

Interface

Uses

Comobj;

Type

TNamespaceExtensionFactory = Class (TcomobjectFactory)

protected

Function GetProgid: String; Override;

public

Procedure UpdateRegistry (Register: Boolean); OVERRIDE;

END;

IMPLEMENTATION

Uses

Windows, Sysutils, ShellView, Shlobj;

(Get short file name)

Function GetshortPath (longpath: ansistring): ANSISTRING

VAR

Szshortpath,

SzlongPath: array [0..max_path] of char; plen: longint;

Begin

Result: = longpath;

Strpcopy (SzlongPath, longpath);

Plen: = getshortpathname (SzlongPath, SzshortPath, Max_Path);

IF not ((Plen = 0) or (Plen> Max_Path)) THEN

Result: = STRPAS (Szshortpath);

END;

Procedure CreateRegKeyex (Const Key, Valuename: string; value: pchar;

Kind, Size: DWORD; Rootkey: HKey;

VAR

Handle: HKEY;

STATUS,

Dispsisition: integer;

Begin

Status: = regReateKeyex (rootkey, pchar (key), 0, '',

Reg_option_non_volatile, key_read or key_write or key_set_value, nil,

Handle, @disposition);

If status = 0 THEN

Begin

Status: = regSetValueex (Handle, Pchar (Valuename), 0, Kind, Value, Size

RegcloseKey (Handle);

END;

IF status <> 0 THEN

Raise Ewin32error.create (SySerrorMessage (STATUS));

END;

Procedure DeleteRegValue (const key, value: string; rootkey: hkey);

VAR

Handle: HKEY;

Status: integer;

Begin

Status: = regopenkey (RootKey, Pchar (key), handle;

If status = 0 THEN

Begin

Status: = regdeletevalue (Handle, Pchar (Valuename));

RegcloseKey (Handle);

END;

IF status <> 0 THEN

Raise Ewin32error.create (SySerrorMessage (STATUS));

END;

{TNAMESPACEEXTENSIONFACTORY}

Function TNamespaceExtensionFactory.getProgid: string;

Begin

Result: = ''; {I don't need progid} for namespace extensions.

END;

Procedure TNamespaceExtensionFactory.UpdateRegistry (Register: boolean);

Const

// Set our extension below my computer

NamespaceKey = 'Software / Microsoft / Windows / CurrentVersion /

Explorer / MyComputer / Namespace / ';

// Requires the registry key required on NT

ApproveKey = 'Software / Microsoft / Windows / CurrentVersion / Shell Extensions / AppRoved /';

VAR

Temp,

CLSID: STRING;

Value: DWORD;

BeginClsid: = guidtostring (classid);

Inherited UpdateRegistry (register);

IF register kil

Begin

Temp: = getshortpath (comser.serverfilename);

CreateRegKey ('CLSID /' CLSID '/' COMSERVER.SERVERKEY, '', TEMP);

IF Win32Platform = VER_PLATFORM_WIN32_NT THEN

CreateRegKeyex (ApproveKey, CLSID, PCHAR (Description), REG_SZ,

Length (Description) 1, HKEY_LOCAL_MACHINE;

CreateRegKeyex ('CLSID /' CLSID '/ InprocServer32 /', 'ThreadingModel',

'Apartment' # 0, REG_SZ, 10, HKEY_CLASS_ROOT;

// This expansion has a node to 'my computer'

CreateRegKeyex (NamespaceKey CLSID, ', Pchar (Description), REG_SZ,

Length (Description) 1, HKEY_LOCAL_MACHINE;

Value: = sfgao_folder; // or sfgao_hassubfolder;

CreateRegKeyex ('CLSID /' CLSID '/ shellfolder /', 'Attributes',

@Value, reg_binary, sizeof (dword), HKEY_CLASSES_ROOT);

// Use the DLL default icon

CreateRegKey ('CLSID /' CLSID '/ Defaulticon', '', Temp ', 0');

end

Else Begin

// Delete the node

RegdeleteKey (HKEY_LOCAL_MACHINE, PCHAR (NAMESPACEKEY CLSID);

IF Win32Platform = VER_PLATFORM_WIN32_NT THEN

DeleteRegValue (AppRoveKey, CLSID, HKEY_LOCAL_MACHINE);

END;

Figure 2.6

END;

End.

The extended operation is shown in Figure 2.6.

in conclusion

Namespace extension is the most complex one in all housing extensions, because its implementation involves a lot of interfaces, and the interaction between the interfaces is also very complicated, Microsoft provides two C version examples, RegView and CabVIEW, Can be used for readers.

转载请注明原文地址:https://www.9cbs.com/read-48084.html

New Post(0)