`
`Part
`
`Figure 7-5 continued
`
`Idi
`Mi ff3 $A
`
`ij$e
`
`iL
`
`rur
`Ai
`
`I1
`
`d1
`i1
`
`ig
`
`4t
`
`1t
`
`if14
`
`LTJ
`
`lb
`
`458
`
`Page 00481
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`case WM_COMMAND
`switch LOWORD wParam
`case IDOK
`Edit_GetText GetOlgitem hWnd IDD_TRACK
`lpti-szTrack
`lpti-szTrack sizeof
`Edit_GetText GetOlgltem hWnd IDD_TIME
`lpti-szlime
`lpti-szTime sizeof
`if Validatelime lpti-szlime
`hWnd
`EndDialog
`
`else
`
`MessageBox
`be entered in nlmss format
`
`hWnd TEXT Track time must
`
`TEXT Error MB_OK
`
`return FALSE/__II EditAlbum dialog procedure
`
`return TRUE
`case IDCANCEL
`
`hWnd
`EndDialog
`return TRUE
`
`break
`
`II
`hWnd
`BOOL CALLBACK EditAlbumDlgProc HWND
`UINT wMsg WPARAM wParam
`LPARAM iParam
`
`ppRecord
`
`static PCEPROPVAL
`static mt nTracks
`PCEPROPVAL
`pRecord pRecPtr
`TCHAR pPtr szTmp
`HWND hwndTList
`hwndCombo
`TRACKINFO ti
`fEnable
`800L
`nLen rc
`
`tNT
`
`switch wMsg
`case WM_INITDIALOG
`PCEPROPVAL
`ppRecord
`
`ppRecord
`
`pRecord
`
`lParam
`
`hwndCombo
`
`hwndTList
`
`Getolgltem hWnd 100_CATEGORY
`GetDlgltern hWnd 100_TRACKS
`
`Edit_LimitText GetDlgltem hWnd
`
`100_NAME MAX_NAMELEN
`
`continue1
`
`459
`
`Page 00482
`
`
`
`II Whidows CE Basics
`
`Part
`
`Figure 7-5 continued
`
`$I
`ii$$ft4
`dAA PN
`qvNc.w
`t414 Ip i_II
`IiTI%4d rWb 1V
`r.4
`
`4i iI
`
`ir
`
`$1
`iIDflI Iut
`
`4jf
`iii EP
`IL
`
`uj1
`
`%w
`
`wir
`
`4iJ á%
`
`1Jb1I
`ij4 mre
`
`460
`
`Page 00483
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`else
`
`EnableWindow GetOlgltem hWnd IDD_DELTRACK
`FALSE
`EnableWlndow GetOlgltem hWnd IDD_EDITTRACK
`FALSE
`
`return TRUE
`
`case IM_COMMAt4D
`hwndlList
`hwndCombo
`
`IDD_TRACKS
`IDD_CATEGORY
`
`GetDlgltem hWnd
`GetDlgltem hWnd
`ppRecord
`pRecord
`switch LOWORD wParam
`case IDD_TRACKS
`switch HIWORD wParara
`case LBN.JJBLCLK
`PostHessage hWnd WM_COMMAND
`MAKELONGIDD_EDITTRACK
`
`break
`case LBN_SELCHANGE
`ListBox_GetCurSel hwndTList
`LB_ERR
`FALSE
`
`fEnable
`
`if
`
`else
`
`TRUE
`fEnable
`EnableWindow GetDlgltem hWnd
`fEnable
`TOD_DELTRACK
`EnableWindow GetDlgltem hWnd
`fEnable
`IDD_EDITTRACK
`
`break
`
`return TRUE
`
`case
`
`IDD_NEWTRACK
`
`sizeof ti
`
`memset ti
`DialogBoxParam hlnst
`TEXT EditTrackDlg hWnd
`LPARAMti
`EditTrackDlgProc
`if rc
`wsprintf szTmp TEXT %s\t%s
`ti.szTrack ti.szTime
`List8ox_GeturSel
`thwndTLisfl
`LB_ERR
`
`rc
`
`if
`
`ListBox_InsertString hwndlLlst
`szTmp
`
`continued
`
`461
`
`Page 00484
`
`
`
`II Whidows CE Bacs
`
`Part
`
`Figure 7-5 continued
`
`ecg.aC .1dptq4
`d4
`4Wt4
`ri41i11IrJ
`1Ih1ImIii 1$maIgl%IskI
`4j%wV vi1 jN
`
`_.igj%s
`IriE1I
`
`iii
`
`NLtv
`iiIp
`
`JI1i
`
`rM Ie JV
`11
`
`ui a1MI $p
`J1
`
`iW
`
`1I PI JiQ
`
`1Li
`
`Iitht
`
`iLib 11
`
`iEf F1k
`
`iaM dN
`
`Ii
`
`462
`
`Page 00485
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`ListBox_SetCurSel hwndTList
`
`return TRUE
`
`II
`
`case TOOK
`Be lazy and assume worst case size values
`sizeof CEPROPVAL
`nLen
`NUM._DB_PROPS
`MAX_NAMELEN
`MAX_ARTISTLEN
`MAXJRACKNAMELEN
`II See If prey record alloc if not
`if pRecord
`II Resize
`if nLen
`
`record if necessary
`intLocalSize pRecord
`
`pRecPtr
`PCEPROPVALLocalReAlloc
`nLen LMEM_MOVEABLE
`
`pRecord
`
`else
`
`else
`
`pRecPtr
`
`pRecord
`
`LocalAlloc
`
`LMEM_FIXED nLen
`
`pRecPtr
`if pRecPtr
`return
`
`the data from the controls to
`II Copy
`II marshaled data block with the structure
`the front and the data in the back
`
`II at
`
`pRecord
`
`nTracks
`
`pRecPtr
`ListBox_GetCount hwndTList
`TCHAR LPBYTEpRecPtr
`NUM_DB_PROPS
`sizeof CEPROPVAL
`II Zero structure to start over
`LocalSize pRecPtr
`memset pRecPtr
`
`pPtr
`
`PlO_NAME
`
`pRecPtr-propid
`pPtr
`pRecPtr-val.lpwstr
`hWnd
`IOD_NAME pPtr
`GetOlgltemlext
`MAX_NAMELEN
`lstrlen pPtr
`pPtr
`pRecPtr
`
`P10_ARTIST
`
`pRecPtr-propid
`pPtr
`pRecPtr-val.lpwstr
`hWnd
`IOD_ARTIST
`GetolgltemText
`MAX_ARTISTLEN
`lstrlen pPtr
`pPtr
`pRecPtr
`
`pPtr
`
`continued
`
`463
`
`Page 00486
`
`
`
`II Wndows CE ascs
`
`Part
`
`Figure 7-5 continued
`
`1p
`
`Th
`
`1I
`
`464
`
`niiSILv41PIIiid
`
`lIIItuIUiI$
`
`LWrr rIiL
`
`iii
`
`L%
`
`twPAiirIp
`
`jI
`
`aIIIiITuI1P
`
`Page 00487
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`II About dialog procedure
`II
`BOOL CALLBACK AboutDlgProc
`
`case
`
`break
`
`return FALSE
`
`virtual
`
`virtual
`
`list view control
`to display the records in the data
`The program uses
`list views dont store any data internally
`base As
`explained in Chapter
`Instead the control makes calls back to the owning window using notification mes
`sages to query the information for each item in the list view control The WM_NOTIFY
`handler OnNotifyMain calls GetltemData to query the database in response to the
`list view control sending LVN_GETDISPINFO notifications The Getltemlnfo func
`database record
`tion first seeks the record to read then reads all
`the properties of
`with one call
`Since the list view control
`typically uses the
`to CeReadRecordProps
`LVN_GETDISPINFO
`notification multiple times for one item Getltemlnfo saves the
`data from the last record read If
`the next read is of the same record the program
`uses the cached data instead of rereading the database
`As Ive explained before you can change the way you sort by simply closing
`in one of the other sort modes The list view control
`the database and reopening it
`then invalidated causing it to again request the data for each record being displayed
`new sort order defined the seek that happens with each database record read
`With
`automatically sorts the data by the sort order defined when the database was opened
`AlbumDB doesnt use the new Ex database functions provided by Windows CE 2.1
`based systems This allows the program to run under earlier versions of the operat
`ing system To modify the example to use separate database volumes only minor
`global variable gguidDB of type CEOID would
`changes would be necessary First
`be added In the DoCreateMain routine code such as the following which mounts
`the volume would be added
`
`is
`
`465
`
`Page 00488
`
`
`
`II WbidoWS CE Eascs
`
`Part
`
`if
`
`OPEN_ALWAYS
`
`\\Albums.cdb
`LCeMountDBVOl g_guidDB TEXT
`failed rc %d
`wsprintf szErr TEXT Database mount
`GetLastErrorO
`NULL szErr
`
`MessageBox
`
`szAppName MB_OK
`
`The following code would be added to the OnDestroyMain routine tounmount
`the volume
`
`if
`
`ICHECK_INVALIDGUID g_guidDB
`g_guidDB
`CeUnniountDBVol
`
`Finally the OpencreateDB routine would be replaced by this version
`
`hWnd mt pnRecords
`
`HANDLE OpenCreateDB HWND
`rc
`INT
`CEOIDINFO oidinfo
`CEDBASEINFO dbi
`
`TCHAR szErr
`
`CENOTIFYREQUEST
`
`cenr
`
`sizeof cenr
`hWnd
`
`g_oidoB
`cenr.dwSize
`
`cenr.hWnd
`
`cenr.dwFlags
`cenr.hHeap
`cenr.dwParam
`
`II Use old style notifications
`
`g_hDB
`
`CeOpenDatabaseEx g_guidoB g_oidoB TEXT
`cenr
`g_nLastSort
`INvALiD_HANDLE_VALUE
`g_hDB
`rc GetLastError
`rc
`ERROR_FILE_NOT_FOUND
`if
`
`\\Albums
`
`if
`
`466
`
`dbi .rgSortSpecs
`dbi.rgSortSpecs
`
`P10_NAME
`
`dbi.rgSortSpecs
`dbi.rgSortSpecs
`
`P10_ARTIST
`
`dbi .rgSortSpecs
`dbi.rgSortSpecs
`
`P10_CATEGORY
`
`CEDB_VALIDCREATE
`dbi.dwFlags
`lstrcpy dbi.szDbaseNanie
`TEXT
`dbi.dwDbaselype
`dbi.wNuniSortOrder
`
`\\Albums
`
`g_oidDB
`
`CeCreateoatabaseEx
`
`g_guidDB dbi
`
`Page 00489
`
`
`
`chapter
`
`Files Databases and the Registry
`
`if g_oidDB
`wsprintf szErr
`TEXT Database create failed rc %d
`GetLastError
`hWnd szErr szAppName MB_OK
`
`MessageBox
`
`return
`
`g_hDB
`
`CeOpenDatabaseEx g_guidDB g_oidDB NULL
`cenr
`g_nLastSort
`
`g_hDB
`else if
`wsprintf szErr
`TEXT Database open
`failed rc %X
`g_hDB GetLastError
`hWnd szErr
`szAppName MB_OK
`
`MessageBox
`
`ext err%d
`
`CeOidGetlnfoEx g_guidDB g_oidDB oidinfo
`oidinfo.infDatabase.wNumRecords
`pnRecords
`return g_hDB
`
`THE REGISTRY
`system database used to store configuration information in applica
`The registry is
`tions and in Windows itself The registry as defined by Windows CE is similar but not
`in function and format to the registries under Windows 98 and Windows NT
`identical
`In other words for an application most of the same registry access
`functions exist
`but the layout of the Windows CE registry doesnt exactly follow either Windows 98
`or Windows NT
`the registry is made up of keys and values Keys
`As in all versions of Windows
`number of pre
`can contain keys or values or both Values contain data in one of
`defined formats Since keys can contain keys the registry is distinctly hierarchical
`The highest level keys the root keys are specified by their predefined numeric con
`stants Keys below the root keys and values are identified by their text name Mul
`tiple levels of keys can be specified in one text string by separating the keys with
`backslash
`
`value the key containing the value must first be opened
`To query or modify
`the value queried and or written then the key closed Keys and values can also be
`enumerated so that an application can determine what
`specific key contains Data
`number of different predefined data types Among
`in the registry can be stored in
`the available data types are strings 32-bit numbers and free form binary data
`
`467
`
`Page 00490
`
`
`
`II Whidows CE Basics
`
`Part
`
`Registry Organization
`
`The Windows CE registry supports three of the high-level
`root keys seen on other
`Windows platforms HKEY_LOCAL_MACHINE HKEY_CURRENT_USER
`and HKEY_
`As with other Windows
`platforms Windows CE uses
`CLASSES_ROOT
`HKEY_LOCAL_MACHINE key to store hardware and driver configuration data the
`data and the HKEY_
`HKEY_CURRtNT_USER to store user-specific configuration
`CLASSES_ROOT key to store file type matching and OLE configuration data
`practical matter the registry is used by applications and drivers to store
`As
`state information that needs to be saved across invocations Applicationstypically
`store
`their current state when they are requested to close and then restore this state when
`location for storing data in the registry by an
`they are launched again The traditional
`application is obtained by means of the following structure
`
`the
`
`ROOT_KEY\SoftwareVcompany
`
`Naine\Icompany Product
`
`In this template the ROOT_KEY is either HKEY_LOCALMACHINE for machine-
`specific data such as what optional components of an application may be installed
`for user-specific information such as the
`on the machine or HKEY_CURRENT..USER
`list of the users last-opened files Under the Software key the companys name that
`wrote the application is used followed by the name of the specific application For
`example Microsoft saves the configuration information for Pocket Word under the key
`
`HKEY_LOCAL_MACHINE\Software\Microsoft\Pocket
`
`Word
`
`While this hierarchy is great for segregating registry values from different ap
`set of keys Because of
`plications from one another
`its best not to create too deep
`value than it does
`takes less memory to store
`the way the registry is designed it
`key Because of this you should design you registry storage so that it uses fewer
`to store more
`its more efficient
`keys and more values To optimize even further
`num
`information in one value than to have the same information stored across
`
`ber of values
`The window in Figure 7-6 shows the hierarchy of keys used to store data for
`Pocket Word The left pane shows the hierarchy of keys down to the Settings key
`the Pocket Word key In the Settings key three values are stored Wrap To
`under
`Window Vertical Scrollbar Visibility
`and Horizontal Scrolibar Visibility
`In this case
`these values are DWORDs but they could have been strings or other data types
`
`468
`
`Page 00491
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`HKEY_CLASSES_ROOT
`HKEY_CURRENT_USER
`HKEY_LOCAL_MACHINE
`Windows CE Services
`
`51
`
`______________________________________________________
`To Wndow
`Wrap
`Vertical Scroilbar Visibilty
`Horizontal Scroilbar Visibiky
`
`TAFT
`
`0nIs
`
`El
`
`mit
`
`Drivers
`
`ExEllodems
`Corn
`
`Printers
`
`El
`
`Software
`
`Microsoft
`Windows CE Services
`
`Tasks
`Pocket Word
`
`151
`
`pwdDefaulWont
`
`pwdCustDict
`11 pwdMRU
`fk pwdRebar
`Sethnps
`
`Converters
`
`Calendar
`
`Clock
`
`Shell
`
`El
`
`Powerpoint
`
`Fvrei
`
`Figure 7-6 You can see the hierarchy of the registry by looking at the values stored by
`Pocket Word
`
`The Registry API
`Now lets turn toward the Windows CE registry API In general
`the registry API pro
`the functions necessary to read and write data in the registry as well as enu
`vides all
`merate the keys and data store within Windows CE doesnt support
`the security
`features of the registry that are supported under Windows NT
`
`Opening and creating keys
`registry key is opened with
`call to this function
`
`LONG RegOpenKeyEx
`
`HKEY hKey LPCWSTR
`OWORD ulOptions
`lpszSubKey
`REGSAM samDesired PHKEY phkResult
`
`the second parameter
`the subkey This
`The first parameter is the key that contains
`previously opened key
`first key must be either one of the root key constants or
`the key to open This
`The subkey to open is specified as
`text string that contains
`subkey string can contain multiple levels of subkeys as long as each subkey is sepa
`backslash For example to open the subkey HKEY_LOCAL_MACHINE\
`rated by
`Software\Microsoft\Pocket Word an application could either call RegOpenKeyEx
`with HKEY_LOCAL_MACHINE as the key and Software\Microsoft\Pocket Word as
`key and then make
`call with
`the subkey or it could open the Software\Microsoft
`
`469
`
`Page 00492
`
`
`
`II Whidows CE Easics
`
`Part
`
`specifying the subkey Pocket Word Key and
`
`that opened handle to RegOpenKeyEx
`value names arent case specific
`Windows CE ignores the ulOptions and samDesired parameters To remain
`compatible with future versions of the operating system that might use security fea
`for ulOptions and NULL for samDesired
`tures these parameters should be set to
`The phkResult parameter should point
`receive the handle to
`to
`variable that will
`the opened key The function if successful returns
`value of ERROR_SUCCESS and
`an error code if
`Another method for opening
`
`it fails
`
`key is
`
`LONG RegCreateKeyEx
`
`HKEY hKey LPCWSTR
`DWORD Reserved
`lpszSubKey
`LPWSTR lpszClass DWORD dwOptions
`REGSAM samDesi red
`LPSECURITY_ATTRIBUTES
`PHKEY phkResult
`
`lpSecurityAttributes
`lpdwDisposition
`LPDWORD
`
`The difference between RegcreateKeyEx and RegOpenKeyEx aside from the extra
`it didnt exist before the call
`parameters is that RegCreateKeyEx
`creates the key if
`two parameters the key handle and the subkey name are the same as in
`The first
`The lpClass parameter
`RegOpenKeyEx The Reserved parameter should be set to
`string that contains the class name of the key if
`its to be created This
`points to
`parameter can be set to NULL if no class name needs to be specified The dwOptions
`NULL and
`and samDesired and lpSecurityAttributes parameters should be set
`NULL respectively The phkResult parameter points to the variable that
`receives the
`handle to the opened or newly created key The lpdwDisposition parameter points
`variable thats set to indicate whether the key was opened or created by the call
`to
`
`to
`
`Reading registry values
`You can query registry values by first opening the key containing the values of inter
`est and calling this function
`
`LONG RegQueryValueEx
`
`HKEY hKey LPCWSTR
`LPDWORD
`
`LPBYTE
`
`ipReserved
`lpData LPDWORD
`
`lpszValueName
`ipType
`LPDWORD
`lpcbData
`
`The hKey parameter
`is the handle of
`the key opened by RegCreateKeyEx or
`RegOpenKeyEx The lpszValueName is the name of the value thats being queried
`The lpType parameter is
`variable that receives
`the variable type This
`pointer
`to
`variable is filled with The lpData parameter points to the buffer to receive the data
`while the lpcbData parameter points to
`the size of the data If
`variable that receives
`to NULL Windows re
`RegQueryValueEx is called with the lpData parameter equal
`turns the size of the data but doesnt return the data itself This allows applications to
`first query the size and type of the data before actually receiving it
`
`470
`
`Page 00493
`
`
`
`Cbapter
`
`Files Databases and the Registry
`
`Writing registry values
`You set
`registry value by calling
`
`LONG RegSetvalueEx
`
`HKEY hKey LPCWSTR lpszValueName DWORD Reserved
`lpData DWORD cbData
`OWORD dwType
`const
`BYTE
`
`The parameters here are fairly obvious the handle to the open key followed by the
`name of the value to set The function also requires that you pass the type of data
`the data itself and the size of the data The data type parameter is simply
`labeling
`aid for the application that eventually reads the data Data in the registry is stored in
`binary format and returned in that same format Specifying
`type has no
`different
`effect on how the data is stored in the registry or how its returned to the application
`However given the availability of third-party registry editors you should make ev
`ery effort to specify the appropriate data type in the registry
`The data types can be one of the following
`
`REG_SZ
`
`zero-terminated Unicode string
`
`REG_EXPAND_SZ
`environment variables
`
`zero-terminated Unicode string with embedded
`
`REG_MULTI_SZ
`
`series of zero-terminated Unicode strings terminated
`by two zero characters
`
`REG_D WORD
`
`REG_BINARY
`
`4-byte binary value
`
`REG_DWORD_BIG_ENDIAN
`
`Free-form binary data
`DWORD value stored in big-endian format
`
`REG_DWORD_11771E_ENDL4N
`
`Equivalent
`
`to REG_DWORD
`
`REGL INK
`
`REG_NONE
`
`REG_RESOUR CE_LIST
`
`Deleting keys and values
`You delete
`registry key by calling
`
`LONG RegDeleteKey
`
`HKEY hKey LPCWSTR lpszSubKey
`
`The parameters are the handle to the open key and the name of the subkey you plan
`the key must not be currently open You
`to delete For the deletion to be successful
`can delete
`value by calling
`
`LONG RegDeleteValue
`
`HKEY hKey LPCWSTR
`
`lpszValueName
`
`471
`
`Page 00494
`
`
`
`II WndoWS CE Basics
`
`Part
`
`wealth of information can be gleaned about
`
`key by calling this function
`
`LONG RegouerylnfoKey
`
`LPDWORD
`
`LPDWORD
`
`LPDWORD
`
`LPDWORD
`
`LPDWORD
`
`PFILETIME
`
`HKEY hKey LPWSTR
`LPDWORD
`ipReserved
`lpcchMaxSubKeyLen
`lpcchMaxClassLen
`lpcValues LPDWORD
`lpcbMaxVaiueData
`lpcbSecurityoescriptor
`lpftLastWriteTinie
`
`lpszClass
`LPDWORD
`
`LPDWORD
`
`lpcchClass
`
`lpcSubKeys
`
`lpcchMaxvalueNanieLen
`
`key The function returns
`The only input parameter to this function is the handle to
`the class of the key if any as well as the maximum lengths of the subkeys and val
`ues under the key The last two parameters the security attributes and the last write
`time are unsupported under Windows CE and should be set to NULL
`
`Closing keys
`You close
`
`registry key by calling
`
`LONG RegCloseKey HKEY hKey
`
`When
`registry key is closed Windows CE flushes any unwritten key data to the
`registry before returning from the call
`
`Enumerating registry keys
`In some instances youll find it helpful
`to be able to query
`and values it contains You accomplish this with two different
`the subkeys another to query the values The first
`function
`
`key to see what subkeys
`functions one to query
`
`LONG RegEnumKeyEx
`
`HKEY hKey DWORD dwlndex
`lpcchName
`LPDWORD
`LPDWORD
`LPWSTR lpszClass
`LPDWORD
`lpcchClass PFILETIME
`
`LPWSTR lpszName
`ipReserved
`
`lpftLastWriteTime
`
`registry key through repeated calls The parameters to
`enumerates the subkeys of
`pass the function are the handle of the opened key and an index value To enumer
`For each subsequent call to
`ate the first subkey the dwlndex parameter should be
`RegEnumKeyEx dwlndex should be incremented to get the next subkey When there
`are no more subkeys to be enumerated RegEnumKeyEx returns ERROR_NO_
`MORE_ITEMS
`For each call to RegEnumKeyEx the function returns the name of the subkey
`and its classname The last write time parameter isnt supported under Windows CE
`key can be enumerated with
`Values within
`call to this function
`
`HKEY hKey DWORD dwlndex
`lpcchValueName
`LPDWORD
`ipType LPBYTE
`
`LPDWORD
`
`LPWSTR
`
`LPDWORD
`
`lpszValueName
`ipReserved
`lpcbData
`lpoata LPDWORD
`
`LONG RegEnuniValue
`
`472
`
`Page 00495
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`Like RegEnumKe this hinction is called repeatedly passing index values to enumerate
`the key When the function returns ERROR_NO_
`the different values stored under
`MORE_ITEMS
`the key RegEnum Value returns the
`there are no more values under
`name of the values the data stored in the value as well as its data type and the size
`of the data
`
`The Reg View Example Program
`
`The following program isa registry viewer application
`to navigate
`the trees in the registry and examine the contents of the data stored Unlike RegFdit
`which is provided by Windows NT and Windows 98 RegView doesnt
`let you edit
`to make Figure 7-7
`such an extension wouldnt he difficult
`the registry However
`the code for the RegView program
`contains
`
`It allows
`
`user
`
`RegView.rc
`
`1/ Resource file
`
`19
`
`ny
`
`include wi
`include regv
`
`II
`
`II
`
`Icons
`
`and bitmaps
`
`regview.ico
`ID_ICON ICON
`ID_BMPS BITMAP TVBmps.bmp
`
`II
`
`II Menu
`
`ID_MENU
`
`MENU DISCARDABLE
`
`ED
`
`POPUP File
`BEGIN
`MENtJITEM Exit
`
`END
`
`Figure 7-7 The Regl
`
`few program
`
`continued
`
`473
`
`Page 00496
`
`
`
`II Whidows CE ascs
`
`Part
`
`Figure 7-7 continued
`
`aw JiPL
`
`Nc
`
`1it
`ahI
`444
`
`IAIrir
`
`jtd
`
`Ji
`
`4JL
`
`i44r1H
`
`ie%i
`
`4P
`
`474
`
`Page 00497
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`struct decodeNotify
`UINT Code
`LRESULT FxnHWND WORD
`
`HWND
`
`LPNMHDR
`
`/1 Structure associates
`
`//
`
`lOs with
`control
`II notify handler
`
`II
`II Generic defines used by application
`define
`define
`
`ID_BMPS
`
`1D....ICON
`
`define
`define
`define
`define
`
`IDC_CMDBAR
`
`ID_MENU
`
`ID_TREEV
`
`ID_LISTV
`
`II Menu
`define
`define
`
`item lOs
`
`1DM_EXIT
`
`1DM_ABOUT
`
`/1
`
`1/ Function prototypes
`
`10
`
`11
`
`12
`
`13
`
`10
`150
`
`int
`
`InitApp HINSTANCE
`InitlnstanCe HINSTANCE
`HWND
`mt Terminstance HINSTANCE
`
`LPWSTR
`lot
`
`int
`
`II App icon resource 10
`resource ID
`
`II Bitmap
`
`II Command band
`1/ Main menu resource ID
`
`ID
`
`/1 Tree view control
`
`1/ List view control
`
`ID
`
`ID
`
`II File menu
`
`II Help menu
`
`HWND
`HTREEITEM
`TNT EnumChildren
`DWORD CountChildren HKEY LPTSTR
`HWND
`LPTSTR
`HKEY
`TNT EnumValues
`TNT DisplayValue HWND
`TNT
`LPTSTR
`TNT GetTree HWND
`HTREEITEM
`HKEY
`InsertTV HWND
`HTREEITEM TCHAR
`HTREEITEM
`TNT TnsertLV HWND
`LPTSTR
`TNT
`LPTSTR
`HWND CreateLV HWND
`HWND CreateTV HWND
`
`HKEY LPTSTR
`LPTSTR
`
`DWORD
`
`PBYTE DWORD
`TNT
`TCHAR
`LPARAM OWORD
`
`RECT
`
`RECT
`
`1/ Window procedures
`LRESULT CALLBACK MainWndProc
`
`HWND UINT WPARAM
`
`LPARAM
`
`/1 Message
`handlers
`HWND UINT WPARAM
`LRESULT DoCreateMain
`LRESULT DoSizeMain HWND UINT WPARAM
`HWND UINT WPARAM
`LRESULT DoNotifyMain
`HWND UINT WPARAM
`LRESULI DoCommandMain
`HWND UINT WPARAM
`LRESULT DoDestroyMain
`
`LPARAM
`LPARAM
`LPARAM
`LPARAM
`LPARAM
`
`continued
`
`475
`
`Page 00498
`
`
`
`II Windows CE Basics
`
`Part
`
`Figure 7-7 continued
`
`111 p4Imch
`
`iI1i
`
`_pIi
`
`mtrp
`
`ar
`
`476
`
`Page 00499
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`II Notification message dispatch
`for MainWindowProc
`const struct decodeNotify MainNotifyltenis
`JD_LISTV OoMainNotifyListv
`ID_TREEV DoMainNotifylreeV
`
`1/
`
`II Program entry point
`/1
`mt WINAPI WinMain
`
`hlnstance HINSTANCE hPrevlnstance
`HINSTANCE
`lpCmdLine mt nCmdShow
`
`LPWSTR
`
`hwndMain
`HWND
`MSG msg
`mt rc
`
`//
`
`rc
`
`Initialize
`application
`InitApp hinstance
`if rc return rc
`
`II
`
`this Instance
`Initialize
`Initlnstance hlnstance lpCmdLine nCmdShow
`
`if
`
`hwndMaln
`hwndMain
`return OxlO
`
`II Application message loop
`while GetMessage msg NULL
`TranslateMessage msg
`jnsg
`
`DispatchMessage
`
`Ofl
`
`Instance cleanup
`II
`return Termlnstance hlnstance msg.wParam
`
`II
`
`II
`
`1/
`mt
`
`InltApp
`
`Application initialization
`
`InitApp HINSTANCE
`WNDCLASS wc
`INITCOMMONCONTROLSEX
`
`hlnstancel
`
`icex
`
`/1 Register application main window class
`wc.style
`wc.lpfnWndProc
`wc.cbClsExtra
`wc.cbWndExtra
`wc.hlnstance
`
`MainWndProc
`
`hlnstance
`
`II Window style
`1/ Callback function
`II Extra class data
`II Extra window data
`
`1/ Owner handle
`
`continued
`
`477
`
`Page 00500
`
`
`
`ii WrndOWS CE Basics
`
`Part
`
`Figure 7-7 continued
`c- h1
`
`4Rpa
`
`tM
`
`mt
`
`ZI
`
`1AV
`
`478
`
`14
`
`Page 00501
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`II
`II Termlnstance
`
`Program cleanup
`
`1/
`mt Termlnstance HINSTANCE
`return nDefRC
`
`hlnstance mt nDefRC
`
`II Message
`
`handling procedures for MainWindow
`
`II
`II MainWndProc
`
`/1
`
`Callback function
`
`for application window
`
`LRESULT
`
`CALLBACK MainWndProc
`
`hWnd UINT wMsg WPARAM wParam
`HWND
`LPARAM lParam
`
`INT
`
`1/ Search message list
`in list
`/1 message
`If
`
`to see if
`
`we need to handle
`call procedure
`
`this
`
`dimMainMessages
`for Ci
`if wMsg MainMessages
`return MainMessages wMsg wParam iParam
`return DefWindowProc hWnd wMsg wParam lParam
`
`/1
`II DoCreateMain
`
`//
`
`Process WM_CREATE message for window
`
`LRESULT DoCreateMain
`
`HWND
`hWnd UINT wMsg WPARAM wParam
`LPARAM lParam
`hwndChild
`
`HWND
`
`hwndCB
`
`nHeight
`INT
`RECT rect
`LPCREATESTRUCT
`
`pcs
`
`1/ Convert
`lParam into pointer
`LPCREATESTRUCT
`lParam
`
`lpcs
`
`to create structure
`
`command bar
`
`that only has
`
`menu and
`
`an
`
`hwndCB
`
`hWnd
`
`II Create minimal
`ii exit button
`CommandBar_Create hlnst
`the menu
`Insert
`II
`hwndCB hlnst
`CommandBar_InsertMenubar
`/1 Add exit button to command bar
`CommandBar_AddAdornments hwndCB
`hwndCB
`commandBar_Height
`nHeight
`
`IDC_CMDBAR
`
`ID_MENU
`
`continued
`
`479
`
`Page 00502
`
`
`
`II Whidows CE
`
`Part
`
`scs
`
`Figure 7-7 continued
`
`Fl
`
`AJ ra r1 ipckBa iN0
`vrlrb
`ii
`NM
`
`gp
`
`riiiI1
`
`Jii
`
`i$h
`
`480
`
`Page 00503
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`nDivPos
`
`rect.right
`
`rectleft
`
`nDivPct/1
`
`SetWindowPos
`
`hwndlV NULL
`rect.left
`rect.bottom
`nDivPos
`SW P_N ZO RD ER
`
`rect.top
`rect.top
`
`SetWindowPos
`
`return
`
`hwndLv
`NULL
`rect.right
`rect.bottom
`
`nDivPos
`
`rect.top
`nflivPos
`rect.le-ft
`rect.top SWP_NOZORDER
`
`If
`II DoCommandMain
`
`Process WM_COMMAND
`
`message
`
`for window
`
`II
`
`LRESULT
`
`WORD
`
`DoCommandMain
`
`hWnd UINT wMsg WPARAM wParam
`HWND
`LPARAM iParais
`idlteni wNotifyCode
`
`HWND hwndCtl
`
`INT
`
`II Parse the parameters
`WORD
`LOWORD wParam
`idltem
`WORD
`HIWORD wParam
`wNotifyCode
`HWND
`iParam
`
`hwndCtl
`
`II Call
`
`for
`
`if
`
`routine to handle control message
`dimMainCommandltems
`i-H-
`MainConimandltems
`idltem
`return MainCommandltemsti.FxnhWnd
`idrtem hwndCtl
`wNotifyCode
`
`return
`
`1/
`/1 DoNotifyMain
`
`1/
`
`Process WM_NOTIFY message
`
`for window
`
`LRESULT DoNotifyMain
`
`HWND
`lINT wMsg
`hWnd
`LPARAM iParam
`
`WPARAM wParam
`
`UINT
`
`HWND
`
`idltem
`hCtl
`
`LPNMHDR pHdr
`INT
`
`II Parse the parameters
`iditem wParam
`LPNMHDR
`pHdr-hwndFronr
`
`pHdr
`
`hCtl
`
`lParam
`
`coilinued
`
`481
`
`Page 00504
`
`
`
`Partil Windows CE Basics
`
`Figure 7-7 continued
`
`f4trnre
`
`41
`
`Fbr
`
`1riNp
`1N4EM1
`
`fau Wit1r
`11 DbNC13W/
`
`1pq
`4S
`1W
`
`it
`
`Y-
`
`iLj WkeI W4
`
`t-iç
`
`111
`
`482
`
`Page 00505
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`II
`
`II DoMainNotifyTreeV
`
`Process notify message for list
`
`view
`
`II
`
`LPARAM DoMainNotifyTreeV
`
`hWnd
`HWND
`LPNMHDR pnrnh
`
`WORD
`
`idltem HWND hwndCtl
`
`LPNM_TREEVI
`
`TCHAR szKey
`
`EW pNoti
`
`fyTV
`
`HKEY hRoot
`HTREEITEM
`hChild hNext
`
`TNT
`
`pNotifylV
`
`LPNM_TREEVIEW
`
`pnmh
`
`switch pnnih-code
`case TVN_ITEr4EXPANDED
`TVE_COLLAPSE
`if pNotlfyTV-action
`on next open they will
`II Delete the children so that
`be reenumerated
`TreeViewGetChild
`hChild
`
`hwndCtl
`
`1/
`
`pNotifylV-iteniNew.hltem
`
`while hChild
`TreeView$etNextltem
`hNext
`
`hwndCtl hChild
`GN_N EXT
`TreeView_Deleteltem hwndCtl hChild
`hNext
`hChild
`
`break
`
`case TVN_SELCHANGED
`Getlree hWnd pNotifylV-itemNew.hlteni
`szKey dimszKey
`EnumValues hWnd hRoot szkey
`break
`
`hRoot
`
`case TVN_ITEMEXPANDING
`
`TVE_EXPAND
`if pNotifylV-action
`Getlree hWnd pNotifylV-itemNew.hltem hRoot
`szKey dimszKey
`hWnd pNotifyTV-itemNew.hltem
`EnumChildren
`hRoot szKey
`
`break
`
`return
`
`con/in ned
`
`483
`
`Page 00506
`
`
`
`II Wndows CE Eascs
`
`Part
`
`Figure 7-7 continued
`
`ir
`
`Sf
`
`gpdr
`
`LV MIQ
`
`13
`
`LJ
`
`11
`
`k4i
`
`ri$ pc
`4III
`r1 ttV r4
`
`i4
`
`jF
`
`_cgra jP
`fi1 tW
`ii
`
`j4
`
`fv
`
`iç
`
`4p
`
`iip
`
`jr
`
`iiiis 41
`
`1lN
`
`PARbiV
`
`idà
`dMsiá
`
`ii
`
`cqLj
`
`if
`
`2t1
`
`484
`
`Page 00507
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`/I Create tree view
`the command bar
`
`1/
`
`Size it
`
`and fills
`
`so that
`it
`fits under
`the left part of
`
`the client area
`
`1/
`
`hwndlV
`
`CreateWindowEx
`
`TEXT
`WS_BURDER
`
`WC_TREEVIEW
`WS_VISIBLE
`WS_VSCRDLL
`WS_CHILD
`TYS_HASLINES
`TVS_HASBUTTONS
`prect-left prect-top
`TVS_LINESATROOI
`prect-right prect-bottom
`HMENUID_TREEV hlnst NULL
`hWnd
`
`II Destroy frame if window not created
`IsWindow hwndTV
`if
`return
`
`control
`
`II
`
`Load
`
`II Create image list
`for tree view icons
`ImageList_Create 16 16 ILC_COLOR
`himl
`from one bitmap
`two
`first
`images
`LoadBitmap hrnst MAKEINTRESOURCE
`hBmp
`ImageList_Add himl hBmp NULL
`ChOmp
`Deleteobject
`
`ID_OMPS
`
`TreeView_SetlmageListhwndTv
`return hwndTV
`
`himl TVSIL_NQRMAL
`
`II
`
`1/
`
`InsertLV
`
`Add an
`
`item to the list
`
`view control
`
`/1
`INT InsertLV HWND
`
`HWND
`hwndLV
`LVITEM lvi
`INT rc
`
`hWnd
`
`INT nltem LPTSTR
`
`pszName
`
`LPTSTR pszData
`
`GetDlgltem hWnd 1D_LISTV
`
`lvi
`
`.mask
`
`lvi.iltem
`
`lvi.iSubltem
`
`LVIF..TEXT
`nitem
`
`LVIF_IMAGE
`
`LVIF_PARAM
`
`lvi.pszText
`lvi.ilmage
`lvi.lParam
`
`pszName
`
`nitem
`hwndLV LVM_INSERTITEM
`SendMessage
`
`rc
`
`LVIF_TEXT
`.mask
`lvi
`lvi.iltem nltem
`lvi.iSubltem
`
`lvi.pszlext
`
`pszData
`
`LPARAMlvi
`
`con/in ned
`
`485
`
`Page 00508
`
`
`
`II Windows CE Basics
`
`Part
`
`Figure 7-7 continued
`
`Mt
`
`ea dI1c
`Dnre
`
`r4Pr
`1W ne ir
`wqc
`
`kIt
`
`1fd
`
`4ir
`
`qtpt4TI
`
`4$ 44W
`
`44
`44
`
`486
`
`Page 00509
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`the item
`the name of
`/1 Get
`tvi.mask
`TVIF_TEXT
`tvi.hltem hltem
`tvi.pszlext
`szName
`dimszName
`tvi.cchTextMax
`TreeView_Getitem hwndTV tvi
`
`lstrcat pszKey
`else
`
`szName
`
`lstrcat pszKey TEXT \\
`TEXT \O
`
`TEXT
`
`the item
`TVIF_PARAM
`
`pszKey
`szName
`Get
`the name of
`ii
`tvi.mask
`TVIF_TEXT
`tvi.hltem hitem
`tvi.pszText
`szName
`dimszName
`tvi.cchTextMax
`if TreeView_Getltem hwndTV tvi
`pRoot
`HTREEITEMtvi.lpararn
`
`else
`
`TNT
`
`rc
`
`GetLastErrorQ
`
`return
`
`II
`
`If DisplayValue
`
`Display the data depending
`
`on
`
`the type
`
`TNT DisplayValue
`
`LPTSTR
`
`pszName
`
`PBYTE pbData
`
`HWND hWnd
`TNT nCnt
`DWDRD dwDSize
`DWORD dwlype
`TCHAR szData
`len
`
`TNT
`
`switch dwType
`case REG_MULTI_SZ
`case REG_EXPAND_SZ
`
`case REG_$Z
`lstrcpy szData LPTSTRpbData
`break
`
`case REG_DWORD
`
`wsprintf szData TEXT %X int pbData
`
`break
`
`ontinwd
`
`487
`
`Page 00510
`
`
`
`II Windows CE 3ascs
`
`Part
`
`Figure 7-7 continued
`
`ji1
`
`Ic
`
`v$IPI
`
`mitmiiijI
`
`Lb1 Ij1P
`
`ipr
`
`4k
`
`L4I
`
`Ii
`
`1r
`
`1\
`
`LJ
`
`488
`
`Page 00511
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`dwNSize
`
`dwDSize
`
`dimszName
`dimbData
`
`nCnt
`RegEnumvalue
`
`rc
`
`hKey nCnt szName dwNSize
`blThta dwDSize
`dwType
`NULL
`
`if hKey
`hRoot
`RegCloseKey hKey
`return
`
`II
`II CountChildren
`
`Count
`
`the number of children of
`
`key
`
`1/
`DWORD CountChildren HKEY hRoot
`TCHAR pEnd
`DWORD dwCnt
`
`HKEY hKey
`
`LPTSTR pszKeyPath LPTSTR pszKey
`
`pEnd
`
`pszKeyPath
`
`istrien pszKeypath
`
`lstrcpy pEnd TEXT \\
`
`lstrcat pEnd pszKey
`
`hKey
`if RegOpenKeyExhRoot
`ERROR_SUCCESS
`pszkeyPath
`dwCnt NULL
`hKey NULL
`NULL NULL
`NULL
`RegouerylnfoKey
`NULL NULL
`NULL NULL
`RegCloseKey hKey
`
`TEXT \O
`
`pEnd
`return dwCnt
`
`/1
`
`II EnumChildren
`
`Enumerate the child keys of
`
`key
`
`1/
`INT EnumChildren
`
`HWND hWnd
`LPTSTR pszKey
`
`HTREEITEM
`
`hParent HKEY hRoot
`
`INT
`
`rc
`DWORD dwNSize
`DWORD dwCSize
`
`TCHAR szName
`
`TCHAR szClassE256
`ft
`FILETIME
`DWORD nChild
`
`HKEY hKey
`TVITEM tvi
`
`contin ned
`
`489
`
`Page 00512
`
`
`
`II Whidows CE Bascs
`
`Part
`
`Figure 7-7 continued
`
`jiP
`Adr
`irJEitIi
`
`4rq/
`
`ir
`
`ikIOw11iI
`4d
`pW
`
`4j
`
`iL
`
`4w
`
`JJ
`
`490
`
`Page 00513
`
`
`
`Chapter
`
`Files Databases and the Registry
`
`hWnd
`EndDialog
`return TRUE
`
`break
`
`return FALSE
`
`The workhorses of this program are the enumeration functions that queiy what
`keys and values are under each key As
`key is opened in the tree view control
`the
`control sends WM_NOTIFY message In response RegView enumerates the items
`below that key and fills
`the tree view with the child keys and the list view control
`with the values
`
`CONCLUSION
`We have covered
`huge amount of ground in this chapter The file system while
`radically different under the covers presents
`standard Win32 interface to the pro
`grammer and
`familiar directory structure to the user The database API is unique to
`Windows CE and provides
`valuable function for the information-centric
`devices that
`Windows CE supports The registry structure and interface are quite familiar to Win
`dows programmers and should present no surprises
`The last two chapters have covered memory and the file system Now its time
`to look at the third part of the kernel triumvirate processes and threads As with the
`other parts of Windows CE the API will be familiar if perhaps
`bit smaller However
`the underlying architecture of Windows CE does make itself known
`
`491
`
`Page 00514
`
`
`
`Page 00515
`
`
`
`Chapter
`
`Processes
`
`and Threads
`
`Like Windows NT Windows CE is
`fully multitasking and multithreaded operating
`system What does that mean In this chapter Ill present
`few definitions and then
`some explanations to answer that question
`single instance of an application If two copies of Microsoft Pocket
`Aprocess is
`are running Every process has its own
`Word are running two unique processes
`protected 32-MB address space as described in Chapter Windows CE enforces
`that can run at any time
`limit of 32 separate processes
`Each process has at least one thread
`thread executes code within
`process
`process can have multiple threads running at the same time put the phrase at the
`same time in quotes because in fact only one thread executes at any instant in time
`The operating system simulates the concurrent execution of threads by rapidly switch
`ing between the threads alternatively stopping one thread and switching to another
`
`PROCESSES
`Windows CE treats processes differently than does Windows 98 or Windows NT First
`and foremost Windows CE has the aforementioned system limit of 32 processes being
`run at any one time When the system starts at least four processes are created NK.EXE
`which provides the kernel services FILESYS.EXE which provides file system services
`GWES.EXE which provides the GUI support and DEVICE.EXE which loads and
`maintains the device drivers for the system On most systems other processes are
`
`493
`
`Page 00516
`
`
`
`II Whidows CE Basics
`
`Part
`
`also started such as the shell EXPLORER.EXE
`and if
`the system is connected
`to
`PC REPLLOG.EXE and RAPISRV.EXE which service the link between the PC and the
`Windows CE system This leaves room for about 24 processes that the u