library documentation

144
PREFACE The library is an important module for any educational institute. Library may contain thousands of books, and its management is a very tough job. The care should be taken for proper distribution of the resources. It should be managed in a manner so that its resources are used efficiently and conveniently. For this rules and rights should be provided to each user. Manual management of such a large system is a very tideous job and errors may occur sometimes. This may affect the integrity and consistency of the system resulting in an improper resource distribution. Here we have provided a full-fledged library management system, which will change the conventional manual management with a computerized library management system. We have tried our best to provide efficient and convenient transectory operations for librarian and users. We are very much thankful to all those who directly or indirectly helped us in completing this project. MIR MUZUMIL ALI ASHOK KUMAR KARTHY b

Upload: mir-muzamil-ali

Post on 30-Mar-2015

619 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: library documentation

PREFACE

The library is an important module for any educational institute. Library may contain thousands of books, and its management is a very tough job. The care should be taken for proper distribution of the resources. It should be managed in a manner so that its resources are used efficiently and conveniently. For this rules and rights should be provided to each user.

Manual management of such a large system is a very tideous job and errors may occur sometimes. This may affect the integrity and consistency of the system resulting in an improper resource distribution.

Here we have provided a full-fledged library management system, which will change the conventional manual management with a computerized library management system. We have tried our best to provide efficient and convenient transectory operations for librarian and users.

We are very much thankful to all those who directly or indirectly helped us in completing this project.

MIR MUZUMIL ALI ASHOK KUMAR

KARTHY

b

Page 2: library documentation

LIBRARY SYSTEM DOCUMENATION

CONTENTS

01. ACKNOWLEDGMENT…………………………………………(a)

02. PREFACE ……………………………………………………… (b)

03. CONTENTS ………………………………………………………2

04. PROJECT SPECIFICATION …………………………………3

05. SOFTWARE STUDY ……………………………………………4

06. THE FORMS ……………………………………………………… 7

07. THE DATABASE ………………………………………………… 8

08. MODULE CODING …………………………………………… 10

09. PROGRAM SOURCE CODING WITH VISUAL SHOTS … 59

10. REPORT SECTION…………………….………………………… 96

11. SETTING SECTION ……………………………………………… 98

12. SUPPORT ……………………………………………………………107

2

Page 3: library documentation

PROJECT SPECIFICATIONS

Project Title: LS Library Management System

Institution: A.M JAIN COLLEGE

Front End Tool: Microsoft Visual Basic 6.0

Back End Tool: Microsoft Office Access 2007

Documentation Tool: Microsoft office Word 2007

Operating System: Microsoft Windows XP

Requirements: Platform:Microsoft Windows 9x, NT and onwards

Hardware: 32-bit Processor, 300 MHz 32 MB RAM, Printer

Submitted By: MIR MUZUMIL ALI.S ASHOK KUMAR.S KARTHY.S

Submitted To: COMPUTER SCIENCE DEPARTMENTA.M JAIN COLLEGEMENAMBAKKAMCHENNAIINDIA

3

Page 4: library documentation

SOFTWARE STUDY

Software used for the development of the project are:

Microsoft Visual Basic 6.0 Microsoft Access 7.0

About Visual Basic 6.0

Visual Basic developed from the old Quick Basic language that was available under the DOS operating system. Quick Basic is the same language as BASIC; it is just Microsoft's product name for its version of BASIC. Visual Basic started out as the Brainchild of Alan Cooper. Cooper developed Visual Basic and then sold the product to Microsoft. Microsoft took the undeveloped product, code-named it "Thunder," the proceeded to create a programming language that would soon become one of the premier development environments in the windows environment.

Features Of Visual Basic

Visual Basic is a superset of the Visual Basic for Applications (VBA) programming language, which is included with most of the office products.

Includes a GUI development environment for development Windows applications.

Provides the ability to develop and test applications using an interpretive run function.

Allows for the creation of p-code and native code EXE files. P-code is a tokenized form of your source code that will be broken down at runtime into machine code. P-code can be stored more efficiently and executed faster than your source code, which is why Visual Basic will create this intermediary form.

Object-based development is possible using class modules. Rapid application development (RAD). Allows for the creation of COM components such as ActiveX

controls, DLLs, and EXEs. Has many internet development possibilities, including the

following:

1. ActiveX documents.2. DHTML applications that help you test browser

application.3. IIS applications that help you build server-based

application.4. Web browser control.5. FTP / HTTP support through a custom control.6. Winsock control.

4

Page 5: library documentation

Has an excellent integrated Help facility and Books Online? Including good debugging facilities. It has many wizards that help automate repetitive tasks.

Can be extended easily through the use of Windows API calls, hundreds of third party controls and DLLs, and integration with other Windows applications through Com and DCOM.

Uses many database access methods to get at different types of data.

Visual Basic Advantages

Visual Basic has many advantages over other development languages. Here's a list of some of these advantages:

Has A shorter learning curve and development time than C/C++, Delphi and even Power Builder.

Removes the complexities of the Windows API form the programmer.

Allows for rapid application development. Excellent for business applications. Used by most of the office suite tools as their macro

language, with the rest to follow. Other companies as well are starting to support VBA in their products, such as AutoCAD, Corel Draw, SAP, and many others.

Allow you to create ActiveX controls. Allows you to reuse third-party controls and component, as

well as your own. Supplies wizards to help you learn the language as well as

to enhance your productivity with the more difficult features of the language.

Object oriented in nature. It's not a complete OOP language, but it's getting closer.

Can integrate with the Internet on both the server side and the client side.

Can create ActiveX Automation servers. Integrates with Microsoft Transaction server. Can run servers either on the same machine or remotely on

another computer. This allows for true distributed processing.

Visual Basic has a large community of developers. (More than 3 million worldwide according to Microsoft). This means continued support for new developers.

MS Access 7.0

5

Page 6: library documentation

Microsoft Access is a powerful RDBMS tool. Microsoft Office Access, previously known as Microsoft Access, is a relational database management system from Microsoft that combines the relational Microsoft Jet Database Engine with a graphical user interface and software-development tools. It is a member of the Microsoft Office suite of applications, included in the Professional and higher editions or sold separately. In mid-May 2010, the current version Microsoft Access 2010 was released by Microsoft in Office 2010; Microsoft Office Access 2007 was the prior version. With its extensive features, it is easier to manage large volume of database. As the project requires large database MS ACCESS 7.0 is the perfect option as a back-end tool. Features of Ms Access 7.0

Users can create tables, queries, forms and reports, and connect them together with macros. Advanced users can use VBA to write rich solutions with advanced data manipulation and user control.The original concept of Access was for end users to be able to "access" data from any source. Other uses include: the import and export of data to many formats including Excel, Outlook, ASCII, dBase, Paradox, FoxPro, SQL Server, Oracle, ODBC, etc. It also has the ability to link to data in its existing location and use it for viewing, querying, editing, and reporting. This allows the existing data to change and the Access platform to always use the latest data. It can perform heterogeneous joins between data sets stored across different platforms. Access is often used by people downloading data from enterprise level databases for manipulation, analysis, and reporting locally.There is also the Jet Database format (MDB or ACCDB in Access 2007) which can contain the application and data in one file. This makes it very convenient to distribute the entire application to another user, who can run it in disconnected environments.One of the benefits of Access from a programmer's perspective is its relative compatibility with SQL (structured query language) — queries can be viewed graphically or edited as SQL statements, and SQL statements can be used directly in Macros and VBA Modules to manipulate Access tables. Users can mix and use both VBA and "Macros" for programming forms and logic and offers object-orientedpossibilities. VBA can also be included in queries.

6

Page 7: library documentation

FORMS:Login form: frmlogin.frmAdd books frmaddbook.frmAdd category frmaddcategory.frmAdd course frmaddcourse.frmReturning books frmreturning.frmBorrower frmborrowing.frmBook catalog frmbookcatalog.frmAdd user frmadduser.frmFind frmfind.frmMain page frmmain.frmChange password frmchangepass.frmAdd user frmuser.frmAbout frmAbout.frm

7

Page 8: library documentation

The Database

Table: Book catalog

This table stores basic information about books; information stored in this table is filled at the time of new book entry data stored in this table are changed only when the table is edited. Access No. is a field which is defined as primary key and it stores the number by which book is uniquely identified.

Columns

Name Type Size

Access_no Text 50

Category Text 50

Table: Borrowers record

This table stores the information about all the borrowed transaction performed. If book is issued or returned to or from staff or student then according changes are made to the table. Access No. is defined as primary key, other information is stored about the staff or student by which any employee can be uniquely identified. Columns

Name Type Size

Borrower id Text 50

Name Text 50

Mi Text 50

Status Text 50

Course Text 50

Add Text 50

Contact Number 50

Table: Category

This table stores the information about all the available books.which can be added or deleted. Columns

8

Page 9: library documentation

Name Type Size

Category Text 50

Table: charge

This table stores the overdue fees which can be increased or decreased according library norms

Columns

Name Type Decimal place

Charge_fee Currency 2

Table: courseThis table stores the courses of the book. This can be

added or deleted.

Name Type SizeCourse Text 50

Table: user list

This table stores the list of users where administrator has full access and other users had limited

Name Type SizeUsername Text 50Password Text 50

MODULESMod drawingOption ExplicitPrivate Declare Function GetLastError Lib "kernel32" () As LongPrivate Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" ( _ ByVal dwFlags As Long, lpSource As Any, dwMessageID As Long, _ ByVal dwLanguageID As Long, lpBuffer As String, _

9

Page 10: library documentation

ByVal nSize As Long, Arguments As Long) As Long' =====================================================================' APIs used primarily for drawing/graphics' =====================================================================Private Declare Function StretchBlt Lib "gdi32" ( _ ByVal hDC As Long, ByVal x As Long, ByVal y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _ ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, _ ByVal nSrcHeight As Long, ByVal dwRop As Long) _ As LongPublic Declare Function DrawState Lib "user32" Alias "DrawStateA" (ByVal hDC As Long, ByVal hBR As Long, ByVal lpDrawStateProc As Long, ByVal lParam As Long, ByVal wParam As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal fuFlags As Long) As LongPrivate Declare Function RealizePalette Lib "gdi32" (ByVal hDC As Long) As LongPrivate Declare Function CopyImage Lib "user32" (ByVal Handle As Long, ByVal ImageType As Long, ByVal newWidth As Long, _ ByVal NewHeight As Long, ByVal lFlags As Long) As LongPrivate Declare Function OleTranslateColor Lib "oleaut32.dll" _ (ByVal lOleColor As Long, ByVal lHPalette As Long, lColorRef As Long) As LongPrivate Declare Function SelectPalette Lib "gdi32" (ByVal hDC As Long, _ ByVal hPalette As Long, ByVal bForceBackground As Long) As LongPublic Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As LongPublic Declare Function GetTextColor Lib "gdi32" (ByVal hDC As Long) As LongPublic Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As LongPublic Declare Function SetBkMode Lib "gdi32" (ByVal hDC As Long, ByVal nBkMode As Long) As LongPublic Const NEWTRANSPARENT = 3 'use with SetBkMode()Private Declare Function CreatePen Lib "gdi32" _ (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As LongPrivate Declare Function MoveToEx Lib "gdi32" _ (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINTAPI) As LongPrivate Declare Function LineTo Lib "gdi32" _ (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As LongPrivate Declare Function Rectangle Lib "gdi32" _ (ByVal hDC As Long, ByVal x1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long' following public functions/types may not be used in these modules but are' used in my CodeSafe program & are here for organizational reasonsPublic Declare Function DrawIconEx Lib "user32" (ByVal hDC As Long, ByVal xLeft As Long, ByVal yTop As Long, ByVal hIcon As Long, ByVal cxWidth As

10

Page 11: library documentation

Long, ByVal cyWidth As Long, ByVal istepIfAniCur As Long, ByVal hbrFlickerFreeDraw As Long, ByVal diFlags As Long) As LongPublic Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As LongPublic Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As LongPublic Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As IntegerPublic Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As LongPrivate Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, lpvParam As NONCLIENTMETRICS, ByVal fuWinIni As Long) As LongPublic Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As LongPrivate Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As LongPrivate Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As LongPrivate Declare Function CreateCompatibleBitmap Lib "gdi32" _ (ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As LongPrivate Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal nPlanes As Long, ByVal nBitCount As Long, lpBits As Any) As LongPrivate Declare Function SetBkColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor As Long) As LongPublic Declare Function GetBkColor Lib "gdi32" (ByVal hDC As Long) As LongPrivate Declare Function PatBlt Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal dwRop As Long) As LongPrivate Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, _ ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, _ ByVal ySrc As Long, ByVal dwRop As Long) As LongPublic Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hDC As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As LongPublic Const DT_CALCRECT = &H400Public Const DT_LEFT = &H0Public Const DT_SINGLELINE = &H20Public Const DT_NOCLIP = &H100Private Const DT_CENTER = &H1

' Types used for fonts & imagesPublic Type POINTAPI x As Long y As LongEnd TypePublic Type LOGFONT lfHeight As Long lfWidth As Long lfEscapement As Long

11

Page 12: library documentation

lfOrientation As Long lfWeight As Long lfItalic As Byte '0=false; 255=true lfUnderline As Byte '0=f; 255=t lfStrikeOut As Byte '0=f; 255=t lfCharSet As Byte lfOutPrecision As Byte lfClipPrecision As Byte lfQuality As Byte lfPitchAndFamily As Byte lfFaceName As String * 32End TypePublic Type RECT Left As Long Top As Long Right As Long Bottom As LongEnd TypePrivate Type TEXTMETRIC tmHeight As Long tmAscent As Long tmDescent As Long tmInternalLeading As Long tmExternalLeading As Long tmAveCharWidth As Long tmMaxCharWidth As Long tmWeight As Long tmOverhang As Long tmDigitizedAspectX As Long tmDigitizedAspectY As Long tmFirstChar As Byte tmLastChar As Byte tmDefaultChar As Byte tmBreakChar As Byte tmItalic As Byte tmUnderlined As Byte tmStruckOut As Byte tmPitchAndFamily As Byte tmCharSet As ByteEnd TypePrivate Type NONCLIENTMETRICS cbSize As Long iBorderWidth As Long iScrollWidth As Long iScrollHeight As Long iCaptionWidth As Long iCaptionHeight As Long lfCaptionFont As LOGFONT iSMCaptionWidth As Long iSMCaptionHeight As Long

12

Page 13: library documentation

lfSMCaptionFont As LOGFONT iMenuWidth As Long iMenuHeight As Long lfMenuFont As LOGFONT lfStatusFont As LOGFONT lfMessageFont As LOGFONTEnd Type' Other constants used for graphicsPrivate Const WHITENESS = &HFF0062Private Const MAGICROP = &HB8074APrivate Const DSna = &H220326 '0x00220326'Color constants for GetSysColorPublic Enum ColConst COLOR_ACTIVEBORDER = 10 COLOR_ACTIVECAPTION = 2 COLOR_ADJ_MAX = 100 COLOR_ADJ_MIN = -100 COLOR_APPWORKSPACE = 12 COLOR_BACKGROUND = 1 COLOR_BTNFACE = 15 COLOR_BTNHIGHLIGHT = 20 COLOR_BTNLIGHT = 22 COLOR_BTNSHADOW = 16 COLOR_BTNTEXT = 18 COLOR_CAPTIONTEXT = 9 COLOR_GRAYTEXT = 17 COLOR_HIGHLIGHT = 13 COLOR_HIGHLIGHTTEXT = 14 COLOR_INACTIVEBORDER = 11 COLOR_INACTIVECAPTION = 3 COLOR_INACTIVECAPTIONTEXT = 19 COLOR_MENU = 4 COLOR_MENUTEXT = 7 COLOR_SCROLLBAR = 0 COLOR_WINDOW = 5 COLOR_WINDOWFRAME = 6 COLOR_WINDOWTEXT = 8End Enum' local variablesPrivate m_hDC As Long ' reference to DC being drawn inPrivate m_Font(0 To 1) As Long ' local copy of menu fontPrivate m_FontOld As Long ' font of DC prior to replacing with menu font

Public Sub DrawRect(ByVal x1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long)' =====================================================================' Simply draws a rectangle using the current DC's background color

13

Page 14: library documentation

' ===================================================================== If m_hDC = 0 Then Exit Sub Call Rectangle(m_hDC, x1, Y1, X2, Y2)End Sub

Public Function GetPen(ByVal nWidth As Long, ByVal Clr As Long) As Long' =====================================================================' Creates a colored pen for drawing' ===================================================================== GetPen = CreatePen(0, nWidth, Clr)End Function

Public Sub DrawCaption(ByVal x As Long, ByVal y As Long, tRect As RECT, _ ByVal hStr As String, hAccel As String, iTab As Integer, _ ByVal Clr As Long, Optional bCenter As Boolean = False, _ Optional iOffset As Integer = 0) ' =====================================================================' Prints text to current DC in the coodinates & colors provided' ===================================================================== If m_hDC = 0 Then Exit Sub 'Equivalent to setting a form's property FontTransparent = True SetBkMode m_hDC, NEWTRANSPARENT Dim OT As Long, x1 As Long ' set text color and set x,y coordinates for printing OT = GetTextColor(m_hDC) SetTextColor m_hDC, Clr x1 = tRect.Right ' print the caption/text If bCenter Then DrawText m_hDC, hStr, Len(hStr), tRect, DT_NOCLIP Or DT_CALCRECT Or DT_CALCRECT Or DT_SINGLELINE tRect.Left = (x1 - iOffset - tRect.Right) \ 2 + iOffset tRect.Right = tRect.Left + tRect.Right Else tRect.Left = x + iOffset End If tRect.Top = y tRect.Bottom = tRect.Bottom + y

14

Page 15: library documentation

DrawText m_hDC, hStr, Len(hStr), tRect, DT_SINGLELINE Or DT_NOCLIP Or DT_LEFT If Len(hAccel) Then ' here we will print an acceleraor key if needed tRect.Left = tRect.Left + iTab - iOffset tRect.Top = y DrawText m_hDC, hAccel, Len(hAccel), tRect, DT_LEFT Or DT_NOCLIP Or DT_SINGLELINE End If 'Restore old text color SetTextColor m_hDC, OTEnd Sub

Public Property Let TargethDC(ByVal vNewValue As Long)' =====================================================================' Maintain a local reference to the DC being drawn in' simply prevents having to pass it to each call to a drawing routine' ===================================================================== m_hDC = vNewValueEnd Property

Public Sub ThreeDbox(ByVal x1 As Long, ByVal Y1 As Long, _ByVal X2 As Long, ByVal Y2 As Long, bSelected As Boolean, _Optional Sunken As Boolean = False)' =====================================================================' Draw/erase a raised/sunken box around the specified coordinates.' =====================================================================

If m_hDC = 0 Then Exit Sub

Dim CurPen As Long, OldPen As Long Dim dm As POINTAPI, iOffset As Integer ' select colors, offset when set indicates erasing iOffset = Abs(CInt(bSelected)) + 1 If Sunken = False Then CurPen = GetPen(1, GetSysColor(Choose(iOffset, COLOR_MENU, COLOR_BTNHIGHLIGHT))) Else CurPen = GetPen(1, GetSysColor(Choose(iOffset, COLOR_MENU, COLOR_BTNSHADOW))) End If

15

Page 16: library documentation

OldPen = SelectObject(m_hDC, CurPen) 'First - Light Line MoveToEx m_hDC, x1 + 2, Y2, dm LineTo m_hDC, x1 + 2, Y1 LineTo m_hDC, X2 - 2, Y1

SelectObject m_hDC, OldPen DeleteObject CurPen ' Next - Dark line If Sunken = False Then CurPen = GetPen(1, GetSysColor(Choose(iOffset, COLOR_MENU, COLOR_BTNSHADOW))) Else CurPen = GetPen(1, GetSysColor(Choose(iOffset, COLOR_MENU, COLOR_BTNHIGHLIGHT))) End If OldPen = SelectObject(m_hDC, CurPen) MoveToEx m_hDC, X2 - 2, Y1, dm LineTo m_hDC, X2 - 2, Y2 LineTo m_hDC, x1 + 2, Y2

' Replace pen & delete temp pen SelectObject m_hDC, OldPen DeleteObject CurPenEnd Sub

Public Sub DrawMenuIcon(lImageHdl As Long, ImageType As Long, _ rt As RECT, bdisabled As Boolean, Optional bInColor As Boolean = True, _ Optional bForceTransparency As Long = 0, Optional iOffset As Integer = 0, _ Optional yOffset As Integer, Optional IMGwidth As Integer = 16, _ Optional IMGheight As Integer = 16, Optional lMask As Long = -1)

' =====================================================================' Draws imagelist image on destined DC' =====================================================================

' ensure the requested image existsIf lImageHdl = 0 Then Exit Sub

Dim lImageSmall As Long, lDrawType As Long, lImageType As LongConst DSS_DISABLED = &H20Const DSS_NORMAL = &H0Const DSS_BITMAP = &H4

16

Page 17: library documentation

Const DSS_ICON = &H3Const CI_BITMAP = &H0Const CI_ICON = &H1Dim rcImage As RECT

If ImageType < 2 Then lDrawType = DSS_BITMAP lImageType = CI_BITMAPElse lDrawType = DSS_ICON lImageType = CI_ICONEnd IflImageSmall = CopyImage(lImageHdl, lImageType, IMGwidth, IMGheight, DSS_NORMAL)If lImageSmall = 0 Then ' failed to make a copy from the imagetype passed, try the other settings If lDrawType = DSS_BITMAP Then lDrawType = DSS_ICON lImageType = CI_ICON Else lDrawType = DSS_BITMAP lImageType = CI_BITMAP End If lImageSmall = CopyImage(lImageHdl, lImageType, IMGwidth, IMGheight, DSS_NORMAL)End IfIf lImageSmall = 0 Then Exit Sub

If bdisabled = False Then ' if not disabled, then straightforward extraction/drawing on coords If ((lImageType = CI_ICON And bForceTransparency < 2) Or bForceTransparency = 2) Then DrawState m_hDC, 0, 0, lImageSmall, 0, rt.Left + iOffset, rt.Top + yOffset, 0, 0, lDrawType Else MakeTransparentBitmap lImageSmall, rt.Left + iOffset, rt.Top + yOffset, IMGwidth, IMGheight, , , lMask End If DeleteObject lImageSmallElse' =====================================================================' This function is from Paul DiLascia's DrawEmbossed function' which draws colored disabled pictures.' To be fair to him, I modified several lines of code so' it is customized for CodeSafe & should it fail -- not his fault' =====================================================================

17

Page 18: library documentation

' // create mono or color bitmap Dim hBitmap As Long If bInColor Then hBitmap& = CreateCompatibleBitmap(m_hDC&, IMGwidth, IMGheight) Else hBitmap& = CreateBitmap(IMGwidth, IMGheight, 1, 1, vbNull) End If' // draw image into memory DC--fill BG white first' // create memory dc Dim hOldBitmap As Long Dim hmemDC As Long hmemDC& = CreateCompatibleDC(m_hDC&) hOldBitmap = SelectObject(hmemDC&, hBitmap&) Call PatBlt(hmemDC&, 0, 0, IMGwidth, IMGheight, WHITENESS) If (lImageType = CI_ICON And bForceTransparency < 2) Or bForceTransparency = 2 Then DrawState hmemDC&, 0, 0, lImageSmall, 0, 0, 0, 0, 0, lDrawType Else MakeTransparentBitmap lImageSmall, 0, 0, IMGwidth, IMGheight, , , lMask, hmemDC End If DeleteObject lImageSmall' // This seems to be required. Dim hOldBackColor As Long hOldBackColor& = SetBkColor(m_hDC&, RGB(255, 255, 255))' // Draw using hilite offset by (1,1), then shadow Dim hbrShadow As Long, hbrHilite As Long hbrShadow& = CreateSolidBrush(GetSysColor(COLOR_BTNSHADOW)) hbrHilite& = CreateSolidBrush(GetSysColor(COLOR_BTNHIGHLIGHT)) Dim hOldBrush As Long hOldBrush& = SelectObject(m_hDC&, hbrHilite&)

Call BitBlt(m_hDC&, rt.Left + 1 + iOffset, rt.Top + 1 + yOffset, IMGwidth, IMGheight, hmemDC&, 0, 0, MAGICROP) Call SelectObject(m_hDC&, hbrShadow&) Call BitBlt(m_hDC&, rt.Left + iOffset, rt.Top + yOffset, IMGwidth, IMGheight, hmemDC&, 0, 0, MAGICROP) Call SelectObject(m_hDC&, hOldBrush&) Call SetBkColor(m_hDC&, hOldBackColor&) Call SelectObject(hmemDC&, hOldBitmap&) Call DeleteObject(hOldBrush&) Call DeleteObject(hbrHilite&) Call DeleteObject(hbrShadow&) Call DeleteObject(hOldBackColor&) Call DeleteObject(hOldBitmap&) Call DeleteObject(hBitmap&) Call DeleteDC(hmemDC&)

18

Page 19: library documentation

End IfEnd Sub

Private Sub MakeTransparentBitmap(imgHdl As Long, _ ByVal xDest As Long, _ ByVal yDest As Long, _ ByVal Width As Long, _ ByVal Height As Long, _ Optional xSrc As Long = 0, _ Optional ByVal ySrc As Long = 0, _ Optional clrMask As OLE_COLOR = -1, _ Optional destDC As Long = 0)' =====================================================================' Borrowed and modified - creates a transparent bitmap' =====================================================================

Dim hdcSrc As Long Dim hbmMemSrcOld As Long Dim hdcMask As Long 'HDC of the created mask image Dim hdcColor As Long 'HDC of the created color image Dim hbmMask As Long 'Bitmap handle to the mask image Dim hbmColor As Long 'Bitmap handle to the color image Dim hbmColorOld As Long Dim hbmMaskOld As Long Dim hPalOld As Long Dim hdcScreen As Long Dim hdcScnBuffer As Long 'Buffer to do all work on Dim hbmScnBuffer As Long Dim hbmScnBufferOld As Long Dim hPalBufferOld As Long Dim lMaskColor As Long Const hPal As Long = 0 On Error Resume Next hdcScreen = GetDC(0&) If destDC = 0 Then destDC = m_hDC hdcSrc = CreateCompatibleDC(hdcScreen) hbmMemSrcOld = SelectObject(hdcSrc, imgHdl) RealizePalette hdcSrc If clrMask < 0 Then clrMask = GetPixel(hdcSrc, 0, 0) OleTranslateColor clrMask, hPal, lMaskColor

'Create a color bitmap to server as a copy of the destination 'Do all work on this bitmap and then copy it back over the

19

Page 20: library documentation

'destination when it's done. hbmScnBuffer = CreateCompatibleBitmap(hdcScreen, Width, Height) 'Create DC for screen buffer hdcScnBuffer = CreateCompatibleDC(hdcScreen) hbmScnBufferOld = SelectObject(hdcScnBuffer, hbmScnBuffer) hPalBufferOld = SelectPalette(hdcScnBuffer, hPal, True) RealizePalette hdcScnBuffer 'Copy the destination to the screen buffer BitBlt hdcScnBuffer, 0, 0, Width, Height, destDC, xDest, yDest, vbSrcCopy 'Create a (color) bitmap for the cover (can't use 'CompatibleBitmap with hdcSrc, because this will create a 'DIB section if the original bitmap is a DIB section) hbmColor = CreateCompatibleBitmap(hdcScreen, Width, Height) 'Now create a monochrome bitmap for the mask hbmMask = CreateBitmap(Width, Height, 1, 1, ByVal 0&) 'First, blt the source bitmap onto the cover. We do this 'first and then use it instead of the source bitmap 'because the source bitmap may be 'a DIB section, which behaves differently than a bitmap. '(Specifically, copying from a DIB section to a monochrome 'bitmap does a nearest-color selection rather than painting 'based on the backcolor and forecolor. hdcColor = CreateCompatibleDC(hdcScreen) hbmColorOld = SelectObject(hdcColor, hbmColor) hPalOld = SelectPalette(hdcColor, hPal, True) RealizePalette hdcColor 'In case hdcSrc contains a monochrome bitmap, we must set 'the destination foreground/background colors according to 'those currently set in hdcSrc (because Windows will 'associate these colors with the two monochrome colors) SetBkColor hdcColor, GetBkColor(hdcSrc) SetTextColor hdcColor, GetTextColor(hdcSrc) BitBlt hdcColor, 0, 0, Width, Height, hdcSrc, xSrc, ySrc, vbSrcCopy 'Paint the mask. What we want is white at the transparent 'color from the source, and black everywhere else. hdcMask = CreateCompatibleDC(hdcScreen) hbmMaskOld = SelectObject(hdcMask, hbmMask)

'When bitblt'ing from color to monochrome, Windows sets to 1 'all pixels that match the background color of the source DC. 'All other bits are set to 0. SetBkColor hdcColor, lMaskColor SetTextColor hdcColor, vbWhite BitBlt hdcMask, 0, 0, Width, Height, hdcColor, 0, 0, _ vbSrcCopy 'Paint the rest of the cover bitmap. ' 'What we want here is black at the transparent color, 'and the original colors everywhere else. To do this, 'we first paint the original onto the cover (which we

20

Page 21: library documentation

'already did), then we AND the inverse of the mask onto 'that using the DSna ternary raster operation '(0x00220326 - see Win32 SDK reference, Appendix, '"Raster Operation Codes", "Ternary 'Raster Operations", or search in MSDN for 00220326). 'DSna [reverse polish] means "(not SRC) and DEST". ' 'When bitblt'ing from monochrome to color, Windows 'transforms all white bits (1) to the background color 'of the destination hdc. All black (0) 'bits are transformed to the foreground color. SetTextColor hdcColor, vbBlack SetBkColor hdcColor, vbWhite BitBlt hdcColor, 0, 0, Width, Height, hdcMask, 0, 0, DSna 'Paint the Mask to the Screen buffer BitBlt hdcScnBuffer, 0, 0, Width, Height, hdcMask, 0, 0, vbSrcAnd 'Paint the Color to the Screen buffer BitBlt hdcScnBuffer, 0, 0, Width, Height, hdcColor, 0, 0, vbSrcPaint 'Copy the screen buffer to the screen BitBlt destDC, xDest, yDest, Width, Height, hdcScnBuffer, 0, 0, vbSrcCopy 'All done! DeleteObject SelectObject(hdcColor, hbmColorOld) SelectPalette hdcColor, hPalOld, True RealizePalette hdcColor DeleteDC hdcColor DeleteObject SelectObject(hdcScnBuffer, hbmScnBufferOld) SelectPalette hdcScnBuffer, hPalBufferOld, True RealizePalette hdcScnBuffer DeleteDC hdcScnBuffer

DeleteObject SelectObject(hdcMask, hbmMaskOld) DeleteDC hdcMask ReleaseDC 0&, hdcScreen SelectObject hdcSrc, hbmMemSrcOld RealizePalette hdcSrc DeleteDC hdcSrc ReleaseDC 0&, hdcScreen End Sub

Public Sub SetMenuFont(bSet As Boolean, Optional hDC As Long, _ Optional bReduced As Boolean = False, Optional otherFont As Long = 0)' =====================================================================' This creates system menu fonts for the destination DC if needed' and either sets it or removes it from the DC

21

Page 22: library documentation

' =====================================================================

' reference the current DC for all drawing If hDC Then m_hDC = hDC If bSet Then ' in order to set the font, we must first determine what it is If m_Font(0) = 0 And otherFont = 0 Then Dim ncm As NONCLIENTMETRICS, newFont As LOGFONT ncm.cbSize = Len(ncm) ' this will return the system font info along with other stuff SystemParametersInfo 41, 0, ncm, 0 ' here we create a memory font based off of system menu font newFont = ncm.lfMenuFont m_Font(0) = CreateFontIndirect(newFont) ' now we are going to try to create a scalable font for ' separator bar text just in case the computer's menu font ' is not scalable. The following is a shortcut way of creating ' the font & I hope it works on all systems! newFont.lfFaceName = "Tahoma" & Chr$(0) newFont.lfCharSet = 1 newFont.lfHeight = (7.5 * -20) / Screen.TwipsPerPixelY 'newFont.lfHeight = newFont.lfHeight + 1 m_Font(1) = CreateFontIndirect(newFont) End If ' add the font to the DC & keep reference to old font ' Calling routines responsbile for restoring original font ' with call back to this routine & a FALSE parameter If m_FontOld = 0 And otherFont = 0 Then m_FontOld = SelectObject(m_hDC, m_Font(Abs(CInt(bReduced)))) Else If otherFont Then SelectObject m_hDC, otherFont Else SelectObject m_hDC, m_Font(Abs(CInt(bReduced))) End If End If Else ' Restoring old font If m_hDC = 0 Then Exit Sub SelectObject m_hDC, m_FontOld End IfEnd Sub

Public Sub DestroyMenuFont()' =====================================================================' Simply destroy the memory font to free up resources

22

Page 23: library documentation

' ===================================================================== On Error Resume Next SelectObject m_hDC, m_FontOld DeleteObject m_Font(0) DeleteObject m_Font(1) m_Font(0) = 0 m_Font(1) = 0End Sub

Public Sub DoGradientBkg(lColor As Long, tRect As RECT, hwnd As Long)'=======================================================================

'=======================================================================

Dim sColor As String, i As Integer, tmpSB As PictureBox, formID As LongDim R As Integer, B As Integer, G As IntegerDim lColorStep As Long, lNewColor As Long

On Error GoTo GradientErrors' we are going to create a picturebox to draw the gradient in' tried drawing directly to hdc via MoveTo & LineTo APIs, but' everytime, it failed -- maybe Win98, maybe my graphics card?' This works though a little slowerformID = GetFormHandle(hwnd)' create the picture box in memorySet tmpSB = Forms(formID).Controls.Add("VB.PictureBox", "pic___tmp_s_b", Forms(formID))With tmpSB ' set picturebox attributes .Visible = False .BorderStyle = 0 .AutoRedraw = True .DrawMode = 13 .DrawWidth = 1 .Height = .ScaleY(tRect.Bottom, vbPixels, .ScaleMode) .Width = .ScaleX(tRect.Right, vbPixels, .ScaleMode) .ScaleMode = vbPixels lNewColor = lColor ' loop thru each line & color it For i = 1 To tRect.Bottom - 1 ' this line is used to subtract/add colors ' for a more dramatic fade, increment the #2 below lColorStep = (2 / tRect.Bottom) * i ' modify the current color B = ((lNewColor \ &H10000) Mod &H100) - lColorStep G = ((lNewColor \ &H100) Mod &H100) - lColorStep

23

Page 24: library documentation

R = (lNewColor And &HFF) - lColorStep ' ensure the Red, Green, Blue values are in acceptable ranges If R < 0 Then R = 0 ElseIf R > 255 Then R = 255 End If If G < 0 Then G = 0 ElseIf G > 255 Then G = 255 End If If B < 0 Then B = 0 ElseIf B > 255 Then B = 255 End If lNewColor = RGB(R, G, B) ' cache the color & draw the line tmpSB.Line (0, i - 1)-(tRect.Right, i - 1), lNewColor, BF Next ' now that the gradient has been drawn, copy it to the menu panel BitBlt m_hDC, 0, 0, tRect.Right, tRect.Bottom, .hDC, 0, 0, vbSrcCopyEnd WithGradientErrors:On Error Resume Next' clean upForms(formID).Controls.Remove "pic___tmp_s_b"Set tmpSB = NothingEnd Sub

Public Sub DrawCheckMark(pRect As RECT, lColor As Long, _ bdisabled As Boolean, Optional xtraOffset As Long = 0)'

=====================================================================' Simple little check mark drawing, looks good 'nuf I think' =====================================================================

Dim CurPen As Long, OldPen As LongDim dm As POINTAPIDim yOffset As Integer, xOffset As IntegerDim x1 As Integer, X2 As IntegerDim Y1 As Integer, Y2 As Integer

24

Page 25: library documentation

CurPen = GetPen(1, lColor)OldPen = SelectObject(m_hDC, CurPen)

xOffset = 6 + xtraOffsetyOffset = pRect.Top + 6

' Here we are simply tracing the outline of a check box' Created by opening a 8x8 bitmap editor and drawing a' simple checkmark from left to right, bottom to topMoveToEx m_hDC, 1 + xOffset, 4 + yOffset, dmLineTo m_hDC, 2 + xOffset, 4 + yOffsetLineTo m_hDC, 2 + xOffset, 5 + yOffsetLineTo m_hDC, 3 + xOffset, 5 + yOffsetLineTo m_hDC, 3 + xOffset, 6 + yOffsetLineTo m_hDC, 4 + xOffset, 6 + yOffsetLineTo m_hDC, 4 + xOffset, 4 + yOffsetLineTo m_hDC, 5 + xOffset, 4 + yOffsetLineTo m_hDC, 5 + xOffset, 2 + yOffsetLineTo m_hDC, 6 + xOffset, 2 + yOffsetLineTo m_hDC, 6 + xOffset, 1 + yOffsetLineTo m_hDC, 7 + xOffset, 1 + yOffsetLineTo m_hDC, 7 + xOffset, 0 + yOffset

' replace original penSelectObject m_hDC, OldPenDeleteObject CurPenEnd Sub

Mod global

Public libCON As ADODB.ConnectionPublic borrowerRS As ADODB.RecordsetPublic catRS As ADODB.RecordsetPublic bookRS As ADODB.RecordsetPublic borrowRS As ADODB.RecordsetPublic currentRS As ADODB.RecordsetPublic courseRS As ADODB.RecordsetPublic returnRS As ADODB.RecordsetPublic feeRS As ADODB.RecordsetPublic userRS As ADODB.RecordsetPublic returnCMD As ADODB.CommandPublic bookCMD As ADODB.CommandPublic borrowerCMD As ADODB.CommandPublic currentCMD As ADODB.CommandPublic feeCMD As ADODB.CommandPublic userCMD As ADODB.CommandPublic courseCMD As ADODB.CommandPublic catCMD As ADODB.CommandPublic SQLstr As String

25

Page 26: library documentation

Public auto As Boolean

Sub main() frmLogin.ShowEnd Sub

Sub dbconnect() Set libCON = New ADODB.Connection libCON.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\Databases\lib_db.mdb;Persist Security Info=False"End Sub

Mod menusOption Explicit

Public Const bAmDebugging As Boolean = FalsePublic Type MenuDataInformation ItemHeight As Integer ItemWidth As Long Icon As Long HotKeyPos As Integer Status As Byte Caption As String OriginalCaption As String Parent As Long ID As LongEnd TypePublic Type PanelDataInformation Height As Long Width As Long HKeyPos As Long SideBar As Long SideBarXY As Long PanelIcon As Long Status As Byte Caption As String FColor As Long BColor As Long SBarIcon As Long ID As LongEnd TypePrivate Type MENUITEMINFO cbSize As Long fMask As Long fType As Long fState As Long wID As Long hSubMenu As Long hbmpChecked As Long hbmpUnchecked As Long

26

Page 27: library documentation

dwItemData As Long dwTypeData As Long cch As LongEnd TypePrivate Type MEASUREITEMSTRUCT CtlType As Long CtlID As Long ItemId As Long ItemWidth As Long ItemHeight As Long ItemData As LongEnd TypePrivate Type DRAWITEMSTRUCT CtlType As Long CtlID As Long ItemId As Long itemAction As Long itemState As Long hwndItem As Long hDC As Long rcItem As RECT ItemData As LongEnd TypePrivate Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128End TypePrivate Type BITMAP bmType As Long bmWidth As Long bmHeight As Long bmWidthBytes As Long bmPlanes As Integer bmBitsPixel As Integer bmBits As LongEnd TypePrivate Type ICONINFO fIcon As Long xHotSpot As Long yHotSpot As Long hbmMask As Long hbmColor As LongEnd Type

' APIs needed to retrieve menu information

27

Page 28: library documentation

Private Declare Function WindowFromDC Lib "user32" (ByVal hDC As Long) As LongPrivate Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As LongPrivate Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As LongPrivate Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As LongPrivate Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As LongPrivate Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As LongPrivate Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As LongPrivate Declare Function SetMenuItemInfo Lib "user32" Alias "SetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, lpcMenuItemInfo As MENUITEMINFO) As LongPrivate Declare Function GetMenuItemInfo Lib "user32" Alias _ "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal uItem As Long, _ ByVal byPosition As Long, lpMenuItemInfo As MENUITEMINFO) As BooleanPublic Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As LongPublic Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As LongPublic Declare Sub CopyMemory Lib "kernel32" Alias _ "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal ByteLen As Long)Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As LongPrivate Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As LongPrivate Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As LongPrivate Declare Function GetIconInfo Lib "user32" (ByVal hIcon As Long, piconinfo As ICONINFO) As LongPrivate Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As LongPrivate Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As LongPrivate Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long' Subclassing APIs & stuffPublic Declare Function CallWindowProc Lib "user32" Alias _ "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hwnd As Long, ByVal MSG As Long, ByVal wParam As Long, _ ByVal lParam As Long) As LongPublic Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" _ (ByVal hwnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As LongPrivate Declare Function SetGraphicsMode Lib "gdi32" (ByVal hDC As Long, ByVal iMode As Long) As LongPrivate Declare Function IsZoomed Lib "user32" (ByVal hwnd As Long) As Long' Subclassing & Windows Message ConstantsPublic Const GWL_WNDPROC = (-4)

28

Page 29: library documentation

Private Const WM_DRAWITEM = &H2BPrivate Const WM_MEASUREITEM = &H2CPrivate Const WM_INITMENU = &H116Private Const WM_INITMENUPOPUP = &H117Private Const WM_ENTERIDLE = &H121Private Const WM_MDICREATE = &H220Private Const WM_MDIACTIVATE = &H222Private Const WM_ENTERMENULOOP = &H211Private Const WM_EXITMENULOOP = &H212

Private Const GMEM_FIXED = &H0Private Const GMEM_ZEROINIT = &H40Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)

' Menu ConstantsPrivate Const MF_BYCOMMAND = &H0Private Const MF_BYPOSITION = &H400Private Const MF_OWNERDRAW = &H100Private Const MF_SEPARATOR = &H800Private Const MFT_SEPARATOR = MF_SEPARATORPrivate Const ODS_SELECTED = &H1Private Const ODT_MENU = 1Private Const MIIM_TYPE = &H10Private Const MIIM_DATA = &H20Private Const MIIM_SUBMENU = &H4

Private MenuData As CollectionPrivate ActiveHwnd As StringPrivate iTabOffset As IntegerPrivate lSubMenu As LongPrivate lMDIchildClosed As LongPrivate VisibleMenus As Collection

Public Sub SetMenus(Form_hWnd As Long, Optional MenuImageList As Control)If bAmDebugging Then Exit Sub

Dim lMenus As Long, Looper As IntegerOn Error Resume NextIf GetFormHandle(Form_hWnd) = -1 Then Exit Sub

lMenus = MenuData(CStr(Form_hWnd)).MainMenuIDIf Err Then ' then new form to subclass ' Initialize a collection of classes if needed If MenuData Is Nothing Then Set MenuData = New Collection Dim NewMenuData As New clsMyMenu ' save the ImageList & Handle to the form's menu With NewMenuData .SetImageViewer MenuImageList .MainMenuID = GetMenu(Form_hWnd)

29

Page 30: library documentation

' used to redirect MDI children to parent for submenu info (see MsgProc:MDIactivate) .ParentForm = Form_hWnd End With ' Add the class to the class collection & remove the instance of the new class MenuData.Add NewMenuData, CStr(Form_hWnd) Set NewMenuData = NothingElse ' form is already subclassed, do nothing! Exit SubEnd IfErr.clearActiveHwnd = CStr(Form_hWnd) ' set collection index to current formCleanMDIchildMenuslMenus = GetMenuItemCount(MenuData(ActiveHwnd).MainMenuID)For Looper = 0 To lMenus - 1 'GetMenuMetrics GetSubMenu(MenuData(ActiveHwnd).MainMenuID, Looper)NextSetFreeWindow True ' hook the window so we can intercept windows messagesEnd Sub

Public Sub ReleaseMenus(hwnd As Long)' =====================================================================' Sub prepares for Forms unloading' This must be placed in the forms Unload event in order to' release memory & prevent crash of program' =====================================================================

If MenuData Is Nothing Then Exit SubOn Error GoTo ByPassReleaseActiveHwnd = CStr(hwnd) ' set current indexSetFreeWindow False ' unhook the windowOn Error Resume NextIf MenuData(ActiveHwnd).ChildStatus = 1 Then lMDIchildClosed = MenuData(ActiveHwnd).ParentFormEnd If' remove references to that form's class & ultimately unload the classMenuData.Remove ActiveHwndIf MenuData.Count = 0 Then ' here we clean up a little when all subclassed forms have been unloaded Set MenuData = Nothing ' erase the collection of classes which will unload the class DestroyMenuFont ' get rid of memory font modDrawing.TargethDC = 0 ' get rid of refrence in that moduleEnd If

30

Page 31: library documentation

ByPassRelease:End Sub

Private Sub CleanMDIchildMenus()' reset parent's menu items (see that routine for remarks)If lMDIchildClosed = 0 Then Exit SubDim Looper As Long, mMenu As Long, mII As MENUITEMINFOmII.cbSize = Len(mII)mII.fMask = &H1 Or &H2mII.fType = 0On Error Resume NextWith MenuData(CStr(lMDIchildClosed)) For Looper = .PanelIDcount To 1 Step -1 mMenu = .GetPanelID(Looper) If GetMenuItemCount(mMenu) < 0 Then .PurgeObsoleteMenus mMenu NextEnd WithlMDIchildClosed = 0End Sub

Public Function MsgProc(ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long

' =====================================================================' Here we determine which messages will be processed, relayed or' skipped. Basically, we send anything thru unless we are measuring' or drawing an item.' =====================================================================

On Error GoTo SendMessageAsIs' the following is a tell-tale sign of a system menuIf lParam = &H10000 Then Err.Raise 5ActiveHwnd = CStr(hwnd) ' ensure index to current form is setSelect Case wMsg Case WM_ENTERMENULOOP 'Debug.Print "entering loop" ' When a menu is activated, no changes can be made to the captions, enabled status, etc ' So we will save each submenu as it is opened and read the info only once, ' this will prevent unnecessary reads each time the submenu is displayed Set VisibleMenus = New Collection Case WM_MDIACTIVATE 'Debug.Print "MDI child created" ' MDI children get their menus subclassed to the parent by Windows ' We set the class's parentform value to the MDI's parent & when ' submenus are processed, they are redirected to the parent

31

Page 32: library documentation

' The ChildStatus is set to clean out the parent's class when the ' child window is closed ' The GetSetMDIchildSysMenu command is run to store the system menu ' with the parent form. When the child is maximized its system menu ' shows up on the parent form & needs to be compared so the class ' doesn't draw for the system menu which it can't do! MenuData(ActiveHwnd).ParentForm = GetParent(GetParent(hwnd)) MenuData(CStr(MenuData(ActiveHwnd).ParentForm)).GetSetMDIchildSysMenu GetSystemMenu(hwnd, False), True MenuData(ActiveHwnd).ChildStatus = 1 Case WM_MEASUREITEM 'Debug.Print "measuring" ' occurs after menu initialized & before drawing takes place ' send to drawing routine to measure the height/width of the menu panel ' If we measured it, don't let windows measure it again If CustomDrawMenu(wMsg, lParam, wParam) = True Then Exit Function Case WM_INITMENUPOPUP ', WM_INITMENU If wParam = 0 Then Err.Raise 5 ' ignore these messages & pass them thru 'Debug.Print "Popup starts" ' Occurs each time a menu is about to be displayed, wMsg is the handle ' Send flag to drawing routine to allow icons to be redrawn CustomDrawMenu wMsg, 0, 0 GetMenuMetrics wParam ' get measurements for menu items ' allow message to pass to the destintation Case WM_DRAWITEM 'Debug.Print "drawing" ' sent numerous times, just about every time the mouse moves ' over the menu. Send flag to redraw menu if needed ' If we drew it, don't let windows redraw it If CustomDrawMenu(wMsg, lParam, wParam) = True Then Exit Function Case WM_EXITMENULOOP 'Debug.Print "exiting loop" ' When a menu is clicked on or closed, we remove the collection of submenus ' so they can be redrawn again as needed Set VisibleMenus = Nothing Case WM_ENTERIDLE 'Debug.Print "Popup ends" ' occurs after the entire menu has been measured & displayed ' at least once. Send flag to not redraw icons CustomDrawMenu wMsg, 0, 0End SelectSendMessageAsIs:MsgProc = CallWindowProc(MenuData(ActiveHwnd).OldWinProc, hwnd, wMsg, wParam, lParam)End Function

Public Function GetMenuIconID(Menu_Caption As String) As Long

32

Page 33: library documentation

' =====================================================================' Returns the icon assigned in the menu caption as a long value' Example: {IMG:9}&Open would return 9' Note: Not used in any modules here, but provided for programmer use' if needed in their applications' =====================================================================Dim i As IntegerOn Error GoTo NoIconi = InStr(Menu_Caption, "{IMG:")If i Then GetMenuIconID = Val(Mid$(Menu_Caption, InStr(Menu_Caption, ":") + 1))End IfExit FunctionNoIcon:GetMenuIconID = 0End Function

Private Sub GetMenuMetrics(hSubMenu As Long)' =====================================================================' Routine gets the meaurements of the submenus & their submenus,' their checked status, enabled status,' control keys, icon index, etc' =====================================================================

Dim lMenus As Long, hWndRedirect As StringDim Looper As Long, meDC As Long, lmnuID As Long, sysMenuLoc As LongDim mII As MENUITEMINFO, mI() As ByteDim tRect As RECT, lMetrics(0 To 10) As LongDim sCaption As String, sBarCaption As StringDim sHotKey As String, bTabOffset As BooleanDim IconID As Integer, iTransparency As IntegerDim bSetHotKeyOffset As Boolean, bNewItem As BooleanDim bHasIcon As Boolean, bRecalcSideBar As LongDim iSeparator As Integer, bSpecialSeparator As Boolean

On Error Resume NextIf MenuData(ActiveHwnd).GetSetMDIchildSysMenu(hSubMenu, False) = True Then Exit SubIf Not VisibleMenus Is Nothing Then ' here we track which submenus are currently visible so we don't ' re-process data which isn't needed until after the submenu is closed lMenus = VisibleMenus(CStr(hSubMenu))

33

Page 34: library documentation

If lMenus Then Exit SubEnd IfOn Error GoTo 0meDC = GetDC(CLng(ActiveHwnd))hWndRedirect = MenuData(ActiveHwnd).ParentForm' Get the ID for the next submenu itemlMenus = GetMenuItemCount(hSubMenu)lSubMenu = hSubMenumodDrawing.TargethDC = meDCDetermineOSWith MenuData(hWndRedirect) ' class for this form For Looper = 0 To lMenus - 1 ' loop thru each subitem ' get the submenu item bSpecialSeparator = False iSeparator = 0: iTransparency = 0 sHotKey = "" ' now set some flags & stuff to return the caption, checked & enabled status ' by referencing the dwTypeData as a byte array vs long or string, ' we bypass the VB crash that happens on Win98 & XP & probably others ReDim mI(0 To 255) mII.cbSize = Len(mII) mII.fMask = &H10 Or &H1 Or &H2 mII.fType = 0 mII.dwTypeData = VarPtr(mI(0)) mII.cch = UBound(mI) ' get the submenu item information GetMenuItemInfo hSubMenu, Looper, True, mII 'Debug.Print lmnuID; "has submenus"; mII.hSubMenu If Abs(mII.wID) = 4096 Or mII.wID = -1 Then Exit Sub lmnuID = mII.wID bNewItem = .SetMenuID(lmnuID, hSubMenu, False, True) sCaption = Left$(StrConv(mI, vbUnicode), mII.cch) If Len(Replace$(sCaption, Chr$(0), "")) = 0 Then sCaption = .OriginalCaption If Left(UCase(sCaption), 9) = "{SIDEBAR:" Then sBarCaption = sCaption 'Debug.Print hWndRedirect; hSubMenu; lmnuID; " Caption: "; sCaption If .OriginalCaption = sCaption And bNewItem = False Then ' here we can get cached info vs reprocessing it again lMetrics(1) = lMetrics(1) + .ItemHeight lMetrics(10) = .ItemWidth If LoWord(lMetrics(10)) > lMetrics(0) Then lMetrics(0) = LoWord(lMetrics(10)) If HiWord(lMetrics(10)) > lMetrics(9) Then lMetrics(9) = HiWord(lMetrics(10)) lMetrics(4) = .SideBarWidth If .Icon <> 0 Then bHasIcon = True If InStr(sCaption, Chr$(9)) Then bTabOffset = True 'Debug.Print "reading existing " & Looper + 1, sCaption Else bNewItem = True

34

Page 35: library documentation

If Len(sBarCaption) > 0 And bRecalcSideBar = 0 Then bRecalcSideBar = lmnuID .OriginalCaption = sCaption .Status = 0 ' new item or change in caption, let's get some measurements ' first extract the caption, controlkeys & icon If InStr(sCaption, Chr$(9)) Then bTabOffset = True ' when Win98 encounters a hotkey above, it automatically ' increases the menu panel width. We need to note that ' so we can decrease the panel widh appropriately and ' offset the automatic increase. This helps prevent extra ' wide menu panels If Left(UCase(sCaption), 9) = "{SIDEBAR:" Then iSeparator = 1 .Status = .Status Or 16 .ItemHeight = 0 .ItemWidth = 0 .Icon = 0 Else 'Debug.Print "Caption "; sCaption FindImageAndHotKey hWndRedirect, sCaption, iTransparency, sHotKey, IconID Debug.Print "iconid="; IconID ' identify whether or not this is a separator iSeparator = Abs(CInt(Len(sCaption) = 0 Or Left$(sCaption, 1) = "-")) If iSeparator = 0 Then iSeparator = Abs(CInt(mII.fType And MF_SEPARATOR) = MF_SEPARATOR) If iSeparator Then IconID = 0 ' no pictures on separator bars! If Len(sCaption) > 0 And iSeparator = 1 Then ' separator bar with text ' calculate entire caption & set a few flags sCaption = Mid$(sCaption, 2) & " " & sHotKey bSpecialSeparator = True sHotKey = "" ' not used for separators End If ' start saving the information .Caption = Trim$(sCaption & " " & sHotKey) .Icon = IconID .Status = .Status Or iTransparency * 4 .Status = .Status Or iSeparator * 2 If IconID Then bHasIcon = True SetMenuFont True, , bSpecialSeparator ' add smaller menu font ' measure the caption width to help identify how wide ' the menu panel should be (greatest width of all submenu items) DrawText meDC, sCaption, Len(sCaption), tRect, DT_CALCRECT Or DT_LEFT Or DT_SINGLELINE Or DT_NOCLIP ' keep track of the largest width, this will be used to ' left align control keys for the entire panel If tRect.Right > lMetrics(0) Then lMetrics(0) = tRect.Right lMetrics(10) = tRect.Right

35

Page 36: library documentation

If iSeparator = 0 Or bSpecialSeparator = True Then ' set min height text menu items to match 16x16 icon height If tRect.Bottom < 10 And bSpecialSeparator = False Then tRect.Bottom = 10 tRect.Bottom = tRect.Bottom + 6 Else tRect.Bottom = 5 ' make default separators 0 height End If ' store the height of the caption text .ItemHeight = tRect.Bottom lMetrics(1) = lMetrics(1) + tRect.Bottom SetMenuFont False If Len(sHotKey) Then .HotKeyPos = Len(sCaption) + 1 ' now do the same for the hotkey DrawText meDC, Trim(sHotKey), Len(Trim(sHotKey)), tRect, DT_CALCRECT Or DT_LEFT Or DT_NOCLIP Or DT_SINGLELINE ' keep track of the widest control key text ' this is used w/widest caption to determine overall ' panel width including icons & checkmarks. Add 12 pixels for ' buffer between end of caption & beginning of control key If tRect.Right > lMetrics(9) Then lMetrics(9) = tRect.Right .ItemWidth = MakeLong(CInt(lMetrics(10)), CInt(tRect.Right)) Else .ItemWidth = MakeLong(CInt(lMetrics(10)), 0) End If End If End If ' we ensure the item is drawn by us ' force a separator status if appropriate mII.fMask = 0 If mII.fType = MF_SEPARATOR Or iSeparator = 1 Then mII.fType = MF_SEPARATOR Or MF_OWNERDRAW Else ' otherwise it's normal mII.fType = mII.fType Or MF_OWNERDRAW End If mII.fMask = mII.fMask Or MIIM_TYPE Or MIIM_DATA ' reset mask ' save updates to allow us to draw the menu item SetMenuItemInfo hSubMenu, Looper, True, mII Next If Looper > 0 Then ' menu items processed If bRecalcSideBar = 0 Then ' sidebar menu id ' if no sidebar was processed, then check the overall panel height ' if it changed, we need to reprocess the sidebar again since ' the graphics & text are centered in the panel If .PanelHeight <> lMetrics(1) And .SideBarItem <> 0 Then bRecalcSideBar = lmnuID End If lMetrics(3) = 5 + Abs(CInt(bHasIcon)) * 18 lMetrics(2) = lMetrics(0) + 12

36

Page 37: library documentation

lMetrics(0) = lMetrics(2) + lMetrics(9) + lMetrics(3) + lMetrics(4) + CInt(bTabOffset) * iTabOffset If bRecalcSideBar Then .SetMenuID bRecalcSideBar, hSubMenu, False, False ReturnSideBarInfo hWndRedirect, sBarCaption, lMetrics(), meDC End If .UpdatePanelID lMetrics(), sBarCaption, (bRecalcSideBar = 0) End IfEnd WithIf Not VisibleMenus Is Nothing Then VisibleMenus.Add 1, (CStr(hSubMenu))' now we replace the default font & release the form's DCSetMenuFont False, meDCReleaseDC CLng(ActiveHwnd), meDCErase lMetricsErase mIEnd Sub

Private Sub FindImageAndHotKey(hWndRedirect As String, sKey As String, imgTransparency As Integer, sAccel As String, imgIndex As Integer)' =====================================================================' This routine extracts the imagelist refrence and resets it if the' image doesn't exist or not imagelist was provided' =====================================================================On Error Resume NextDim i As Integer, sSpecial As String, sHeader As StringimgIndex = 0imgTransparency = 0If Left$(UCase(sKey), 5) = "{IMG:" Then i = InStr(sKey, "}") If i Then sHeader = UCase(Left$(sKey, i)) sKey = Mid$(sKey, i + 1) ' extract the image index imgIndex = Val(Mid$(sHeader, 6)) ' if the value<1 or >nr of images, then reset it to zero Debug.Print "icon count="; MenuData(hWndRedirect).TotalIcons If imgIndex < 1 Or imgIndex > MenuData(hWndRedirect).TotalIcons Then imgIndex = 0 Else ' optional transparency flag ' Y=always use transparency ' N=never user transparency ' default: Icons never use transparency, Bitmaps always If InStr(sHeader, "|Y}") Then imgTransparency = 1 If InStr(sHeader, "|N}") Then imgTransparency = 2 End If End If

37

Page 38: library documentation

End If' Parse the Caption & the Control KeysAccel = ""' First let's see if it's a menu builder supplied control key' if so, it's easy to identify 'cause it is preceeded by a vbTabi = InStr(sKey, Chr$(9))If i Then ' yep, menu builder supplied control key sAccel = Trim$(Mid$(sKey, i + 1)) sKey = Trim$(Left$(sKey, i - 1))Else ' user supplied control key, a little more difficult to find For i = 1 To 3 ' look for Ctrl, Alt & Shift combinations 1st If InStr(UCase(sKey), Choose(i, "CTRL+", "SHIFT+", "ALT+")) Then ' if found, then exit routine sAccel = Trim$(Mid$(sKey, InStr(UCase(sKey), Choose(i, "CTRL+", "SHIFT+", "ALT+")))) sKey = Trim$(Left$(sKey, InStr(UCase(sKey), Choose(i, "CTRL+", "SHIFT+", "ALT+")) - 1)) Exit Sub End If Next For i = 1 To 15 ' look for F keys next If Right$(UCase(sKey), Len("F" & i)) = "F" & i Then ' if found, then exit routine sAccel = Trim$(Mid$(sKey, InStrRev(UCase(sKey), "F" & i))) sKey = Trim$(Left$(sKey, InStrRev(UCase(sKey), UCase(sAccel)) - 1)) Exit Sub End If Next ' here we look for other types of hot keys, these can be customized ' as needed by following the logic below For i = 1 To 6 ' hot key looking for, it will be preceded by a space and must ' be at end of caption, otherwise we ignore it sSpecial = Choose(i, " DEL", " INS", " HOME", " END", " PGUP", " PGDN") If Right$(UCase(sKey), Len(sSpecial)) = sSpecial Then sAccel = Trim$(Mid$(sKey, InStrRev(UCase(sKey), sSpecial))) sKey = Trim$(Left$(sKey, InStrRev(UCase(sKey), sSpecial) - 1)) Exit For End If NextEnd IfEnd Sub

Private Sub ReturnSideBarInfo(hWndRedirect As String, sBarInfo As String, vBarInfo() As Long, tDC As Long)' =======================================================================' This routine returns the sidebar information for the current submenu

38

Page 39: library documentation

' Basically we are parsing out the SIDEBAR caption' =======================================================================

Dim i As Integer, sImgID As StringDim lRatio As Single, sText As StringDim bMetrics As Boolean, sTmp As StringDim lFont As Long, lFontM As LOGFONT, hPrevFont As LongDim tRect As RECTDim imgInfo As BITMAP, picInfo As ICONINFODim TempBMP As Long, ImageDC As Long, sbarType As Integer

' here we are just adding a delimeter at end of string to make parsing easierIf Right$(sBarInfo, 1) = "}" Then sBarInfo = Left$(sBarInfo, Len(sBarInfo) - 1)sBarInfo = sBarInfo & "|"' stripoff the SIDEBAR headeri = InStr(UCase(sBarInfo), "{SIDEBAR:")sBarInfo = Mid$(sBarInfo, InStr(sBarInfo, ":") + 1)' return the type of sidebar Image or Texti = InStr(sBarInfo, "|")' if the next line <> TEXT then we have an image handle or image controlsImgID = Left$(sBarInfo, i - 1)

On Error Resume Next' can't leave memory fonts running around loose -- wasted memoryIf MenuData(hWndRedirect).SideBarIsText = True And MenuData(hWndRedirect).SideBarItem <> 0 Then ' kill the previous font for this item, if any DeleteObject MenuData(hWndRedirect).SideBarItemEnd IfvBarInfo(10) = 0 ' reset to force no sidebar' use with caution. Making width too small or too large' may prevent menu from displaying or crash on memory' suggest using between 32 & 64If InStr(UCase(sBarInfo), "|WIDTH:") Then ' width of the sidebar (user-provided) ' undocumented! this allows the sidebar width to be modified vBarInfo(4) = Val(Mid$(sBarInfo, InStr(UCase(sBarInfo), "|WIDTH:") + 7))Else ' however, 32 pixels wide seems to look the best vBarInfo(4) = 32 ' default width of sidebarsEnd IfIf IsNumeric(sImgID) Then ' user is providing image handle vs a form picture object vBarInfo(10) = Val(sImgID) ' ref to picture if it exists sbarType = 2 ' status: image sidebar vBarInfo(9) = 8 ' type default as bmpElse If sImgID = "TEXT" Then sbarType = 4 ' status: text sidebar

39

Page 40: library documentation

vBarInfo(9) = 0 If InStr(UCase(sBarInfo), "|CAPTION:") Then sText = Mid$(sBarInfo, InStr(UCase(sBarInfo), "|CAPTION:") + 9) i = InStr(sText, "|") sText = Left$(sText, i - 1) End If sBarInfo = UCase(sBarInfo) ' make it easier to parse If InStr(sBarInfo, "|FONT:") Then ' parse out the font sTmp = Mid$(sBarInfo, InStr(sBarInfo, "|FONT:") + 6) i = InStr(sTmp, "|") sTmp = Left$(sTmp, i - 1) Else sTmp = "Arial" ' default if not provided End If lFontM.lfCharSet = 0 ' scalable only lFontM.lfFaceName = sTmp ' if user wants other font attributes, then make it so If InStr(sBarInfo, "|BOLD") Then sTmp = sTmp & " Bold" If InStr(sBarInfo, "|ITALIC") Then sTmp = sTmp & " Italic" lFontM.lfFaceName = sTmp & Chr$(0) If InStr(sBarInfo, "|UNDERLINE") Then lFontM.lfUnderline = 1 ' if user wants a different fontsize then make it so If InStr(sBarInfo, "|FSIZE:") Then i = Val(Mid$(sBarInfo, InStr(sBarInfo, "|FSIZE:") + 7)) If i < 4 Then i = 12 ' min & max fonts If i > 24 Then i = 24 Else i = 12 ' default font size End If Do ' here we are going to create fonts to see if it will ' fit in the sidebar, unfortunately we need to do this ' each time the menubar is initially displayed or resized because ' the sidebar height may have changed with adding/removing ' or making menu items invisible lFontM.lfHeight = (i * -20) / Screen.TwipsPerPixelY ' can't rotate the font before measuring it - per MSDN drawtext won't measure rotated fonts lFont = CreateFontIndirect(lFontM) ' create the font without rotation hPrevFont = SelectObject(tDC, lFont) ' load it into the DC ' see if it will fit in the sidebar DrawText tDC, sText, Len(sText), tRect, DT_CALCRECT Or DT_LEFT Or DT_SINGLELINE Or DT_NOCLIP Or &H800 ' regardless we delete the font, cause we'll need to rotate it SelectObject tDC, hPrevFont DeleteObject lFont If tRect.Right > vBarInfo(1) Or tRect.Bottom > vBarInfo(4) Then ' font is too big, reduce it by 1 and try again i = i - 1

40

Page 41: library documentation

If i < 4 Then Exit Do Else ' font is ok, now we rotate it & save it lFontM.lfEscapement = 900 lFont = CreateFontIndirect(lFontM) ' create the font vBarInfo(10) = lFont ' save it vBarInfo(8) = tRect.Right ' measurements vBarInfo(5) = tRect.Bottom Exit Do End If Loop Else ' here we have an image/picturebox control containing an image ' we need to extract the image handle Dim formID As Long, vControl As Control, bIsMDI As Boolean ' loop thru each open form to determine which is the active formID = GetFormHandle(CLng(hWndRedirect), bIsMDI) If formID > -1 Then sbarType = 2 'status: image sidebar ' let's see if the control passed is indexed If Right$(sImgID, 1) = ")" Then ' indexed image i = InStrRev(sImgID, "(") sTmp = Left$(sImgID, i - 1) i = Val(Mid$(sImgID, i + 1)) If bIsMDI Then If Forms(formID).ActiveForm Is Nothing Then Set vControl = Forms(formID).Controls(sTmp).Item(i) Else ' when control is in an MDIs active form, we reference it this way Set vControl = Forms(formID).ActiveForm.Controls(sTmp).Item(i) End If Else Set vControl = Forms(formID).Controls(sTmp).Item(i) End If Else If bIsMDI Then If Forms(formID).ActiveForm Is Nothing Then Set vControl = Forms(formID).Controls(sImgID) Else ' when control is in an MDIs active form, we reference it this way Set vControl = Forms(formID).ActiveForm.Controls(sImgID) End If Else Set vControl = Forms(formID).Controls(sImgID) End If End If ' cache the picture handle & type vBarInfo(10) = vControl.Picture.Handle If vControl.Picture.Type = 3 Then vBarInfo(9) = 16 Else vBarInfo(9) = 8 Set vControl = Nothing End If

41

Page 42: library documentation

End IfEnd IfIf vBarInfo(10) = 0 Then 'failed retrieving sidebar information Debug.Print "Sidebar failed" vBarInfo(4) = 0 Exit SubEnd IfsBarInfo = UCase(sBarInfo) ' make it easier to parse'ok, let's get the rest of the attributesIf InStr(sBarInfo, "|BCOLOR:") Then ' Background color for the sidebar Select Case Left$(Mid$(sBarInfo, InStr(sBarInfo, "|BCOLOR:") + 8), 4) Case "NONE": vBarInfo(6) = -1 Case "BACK": ' short for background ' if a text sidebar & background was provided we change to default If sbarType = 2 Then vBarInfo(6) = -2 Else vBarInfo(6) = -1 Case Else ' numeric background color -- use it vBarInfo(6) = Val(Mid$(sBarInfo, InStr(sBarInfo, "|BCOLOR:") + 8)) End SelectElse vBarInfo(6) = -1 ' default: use the menubar background colorEnd IfIf vBarInfo(6) = -1 Then vBarInfo(6) = GetSysColor(COLOR_MENU)If vBarInfo(10) Then If sbarType = 2 Then ' now if an image sidebar, we call subroutine for more attributes GoSub DrawPicture ' let's get the size of the image vs the size of the menu panel & ' either center or shrink the image to fit ' we will return the left offset, top offset & new image width, height If vBarInfo(5) > vBarInfo(4) Or vBarInfo(8) > vBarInfo(1) Then ' image is larger than menu panel If vBarInfo(5) / vBarInfo(4) > vBarInfo(8) / vBarInfo(1) Then lRatio = vBarInfo(4) / vBarInfo(5) Else lRatio = vBarInfo(1) / vBarInfo(8) End If vBarInfo(5) = CInt(vBarInfo(5) * lRatio) vBarInfo(8) = CInt(vBarInfo(8) * lRatio) End If vBarInfo(7) = MakeLong(CInt(vBarInfo(5)), CInt(vBarInfo(8))) ' save the left & top offsets for the image, this way we don't have ' to remeasure when the menu is being displayed. vBarInfo(5) = MakeLong((vBarInfo(4) - vBarInfo(5)) \ 2, (vBarInfo(1) - vBarInfo(8)) \ 2) Else ' if user want's gradient background for text sidebar then If InStr(sBarInfo, "|GRADIENT") > 0 And sbarType = 4 Then vBarInfo(9) = vBarInfo(9) Or 32

42

Page 43: library documentation

' text sidebar, let's get the forecolor of the text & black is default If InStr(sBarInfo, "|FCOLOR:") Then vBarInfo(7) = Val(Mid$(sBarInfo, InStr(sBarInfo, "|FCOLOR:") + 8)) If vBarInfo(7) < 0 Then vBarInfo(7) = 0 Else vBarInfo(7) = 0 End If vBarInfo(5) = MakeLong(CInt(vBarInfo(5)), CInt(vBarInfo(8))) End IfEnd IfvBarInfo(9) = sbarType Or vBarInfo(9)vBarInfo(0) = vBarInfo(0) + vBarInfo(4)'Debug.Print "font?"; (vBarInfo(9) And 4) = 4; vBarInfo(10)sBarInfo = sTextExit Sub

DrawPicture:' this routine is used when....' 1. When we need the background color for a mask' 2. Image passed is a control to get height/width values'Get the info about our imageIf GetObject(vBarInfo(10), Len(imgInfo), imgInfo) = 0 Then 'And vControl Is Nothing Then GetIconInfo vBarInfo(10), picInfo If picInfo.xHotSpot = 0 Or picInfo.yHotSpot = 0 Then 'if the image passed was a handle vs control and not a bitmap ' sidebar fails Debug.Print "Sidebar failed image is not a bitmap or icon type" vBarInfo(10) = 0 vBarInfo(4) = 0 Return End If vBarInfo(9) = 16 vBarInfo(5) = picInfo.xHotSpot vBarInfo(8) = picInfo.yHotSpotElse vBarInfo(9) = 8 vBarInfo(5) = imgInfo.bmWidth vBarInfo(8) = imgInfo.bmHeightEnd IfErr.clearIf vBarInfo(6) = -2 Then Dim picIcon As PictureBox Forms(formID).Controls.Add "VB.PictureBox", "pic___Ic_on_s", Forms(formID) With Forms(formID).Controls("pic___Ic_on_s") .Visible = False .AutoRedraw = True If vBarInfo(6) = -2 Then If vBarInfo(9) = 8 Then i = 4 Else i = 3 ' draw the image to the picturebox

43

Page 44: library documentation

If DrawState(.hDC, 0, 0, vBarInfo(10), 0, 0, 0, 0, 0, CLng(i)) = 0 Then ' drawing failed, try again with differnt picture type If i = 4 Then i = 3 Else i = 4 DrawState .hDC, 0, 0, vBarInfo(10), 0, 0, 0, 0, 0, CLng(i) End If ' get the mask color vBarInfo(6) = GetPixel(.hDC, 0, 0) End If End With Forms(formID).Controls.Remove "pic___Ic_on_s"End IfReturnEnd Sub

Private Sub SetFreeWindow(bSet As Boolean)' =====================================================================' This routine hooks or unhooks a window & is used when' menus are first set and when a form closes' =====================================================================

If MenuData(ActiveHwnd).OldWinProc = 0 And bSet = True Then ' hook only if window not already hooked MenuData(ActiveHwnd).OldWinProc = SetWindowLong(CLng(ActiveHwnd), GWL_WNDPROC, AddressOf MsgProc)Else If MenuData(ActiveHwnd).OldWinProc <> 0 And bSet = False Then ' hook only if window was already hooked SetWindowLong CLng(ActiveHwnd), GWL_WNDPROC, MenuData(ActiveHwnd).OldWinProc MenuData(ActiveHwnd).OldWinProc = 0 End IfEnd IfEnd Sub

Private Function CustomDrawMenu(wMsg As Long, lParam As Long, wParam As Long) As Boolean' =====================================================================' Here we simply measure & draw menu items based on settings saved' in the form's related class' =====================================================================

Dim IsSep As Boolean, hWndRedirect As String

44

Page 45: library documentation

Static bDrawIcon As Boolean, bDrawPanel As Boolean, bGetPanelData As BooleanStatic lOffsets(0 To 2) As Long, lLastSubMenu As Long' MDI children menus are subclassed to parent by Windows' However, if the child isn't maximized in the MDI parent, then the menus are' not subclassed (pain in the neck until this was figured out & re-thought)' To work around this & prevent the submenus from being stored in both the parent' and child classes, I redirect the actions to the parent via the GetMenuMetrics sub' regardless whether or not the child is maximized' Since each menu drawn is now stored the parent class, we redirect to the routine to' get the info from the parent. If the form is the MDI parent or is a non-MDI form,' then the ParentForm property is the same as the form's actual handlehWndRedirect = MenuData(ActiveHwnd).ParentForm ' here we set this flag.

Select Case wMsgCase WM_INITMENUPOPUP ' menu is about to be displayed, set flag to allow drawing of icons bDrawIcon = True: bDrawPanel = True: bGetPanelData = True lLastSubMenu = 0Case WM_DRAWITEM Dim DrawInfo As DRAWITEMSTRUCT Dim IsSideBar As Boolean Dim hBR As Long, hOldBr As Long, hChkBr As Long Dim hPen As Long, hOldPen As Long, lTextColor As Long Dim tRect As RECT Dim iRectOffset As Integer, iSBoffset As Integer Dim sAccelKey As String, sCaption As String Dim bMenuItemDisabled As Boolean, bMenuItemChecked As Boolean Dim bSelected As Boolean, bHasIcon As Boolean 'Get DRAWINFOSTRUCT which gives us sizes & indexes Call CopyMemory(DrawInfo, ByVal lParam, LenB(DrawInfo)) ' only process menu items, other windows items send above message ' and we don't want to interfere with those. Also if we didn't ' process it, we don't touch it lSubMenu = DrawInfo.hwndItem If MenuData(hWndRedirect).SetMenuID(DrawInfo.ItemId, DrawInfo.hwndItem, False, False) = False Then Exit Function If DrawInfo.CtlType <> ODT_MENU Then Exit Function CustomDrawMenu = True IsSideBar = CBool((MenuData(hWndRedirect).Status And 16) = 16) If (IsSideBar = True And bDrawPanel = False) Then Exit Function IsSep = (MenuData(hWndRedirect).Status And 2) = 2 And IsSideBar = False ' get the checked & enabled status bMenuItemDisabled = CBool((DrawInfo.itemState And 6) = 6 Or (DrawInfo.itemState And 7) = 7) ' don't continue the process if the disabled item or separator ' was already drawn, no need to redraw it again - it doesn't change If bDrawIcon = False And (bMenuItemDisabled = True Or IsSep = True) Then Exit Function

45

Page 46: library documentation

bMenuItemChecked = CBool((DrawInfo.itemState And 8) = 8 Or (DrawInfo.itemState And 9) = 9) ' set a reference in the drawing module to this menu's DC & set the font modDrawing.TargethDC = DrawInfo.hDC If bDrawPanel = True Or lLastSubMenu <> DrawInfo.hwndItem Then Dim pData(0 To 10) As Long MenuData(hWndRedirect).GetPanelInformation pData(), sCaption lOffsets(2) = pData(3) If lOffsets(2) Then lOffsets(2) = lOffsets(2) + 5 lOffsets(1) = pData(4) If pData(4) Then lOffsets(1) = lOffsets(1) + 3 lOffsets(0) = lOffsets(1) + lOffsets(2) If bDrawPanel = True Then If pData(10) <> 0 Then Debug.Print "panel xy:"; pData(4), pData(1) tRect.Bottom = pData(1) tRect.Right = pData(4) hBR = CreateSolidBrush(pData(6)) hPen = GetPen(1, pData(6)) hOldPen = SelectObject(DrawInfo.hDC, hPen) hOldBr = SelectObject(DrawInfo.hDC, hBR) DrawRect 0, 0, tRect.Right, tRect.Bottom SelectObject DrawInfo.hDC, hOldBr DeleteObject hBR SelectObject DrawInfo.hDC, hOldPen DeleteObject hPen pData(8) = CLng(HiWord(pData(5))) pData(5) = CLng(LoWord(pData(5))) If (pData(9) And 2) = 2 Then modDrawing.TargethDC = DrawInfo.hDC DrawMenuIcon pData(10), Abs(CInt((pData(9) Or 16) = 16) * 2) + 1, _ tRect, False, , 2, CInt(pData(5)), CInt(pData(8)), LoWord(pData(7)), HiWord(pData(7)), pData(6) Else SetBkMode DrawInfo.hDC, NEWTRANSPARENT DetermineOS DrawInfo.hDC If (pData(9) And 32) = 32 Then DoGradientBkg pData(6), tRect, CLng(hWndRedirect) SetMenuFont True, , , pData(10) tRect.Left = (pData(4) - pData(5)) \ 2 tRect.Top = (pData(1) - pData(8)) \ 2 + pData(8) SetTextColor DrawInfo.hDC, pData(7) DrawText DrawInfo.hDC, sCaption, Len(sCaption), tRect, DT_LEFT Or DT_NOCLIP Or DT_SINGLELINE Or &H800 SetMenuFont False End If End If End If bDrawPanel = False lLastSubMenu = DrawInfo.hwndItem

46

Page 47: library documentation

Erase pData End If If IsSideBar Then CustomDrawMenu = True Exit Function End If SetMenuFont True ' determine if this item is focused or not which also determines ' what colors we use when we are drawing bSelected = (DrawInfo.itemState And ODS_SELECTED) = ODS_SELECTED ' Now let's set some colors to draw with With DrawInfo If bSelected = True And bMenuItemDisabled = False And IsSep = False Then hBR = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)) hPen = GetPen(1, GetSysColor(COLOR_HIGHLIGHT)) lTextColor = GetSysColor(COLOR_HIGHLIGHTTEXT) Else hBR = CreateSolidBrush(GetSysColor(COLOR_MENU)) hPen = GetPen(1, GetSysColor(COLOR_MENU)) If bMenuItemDisabled Or IsSep = True Then lTextColor = GetSysColor(COLOR_HIGHLIGHTTEXT) Else lTextColor = GetSysColor(COLOR_MENUTEXT) End If End If If bMenuItemDisabled = True Then ' for checked & disabled items, we use default back color hChkBr = CreateSolidBrush(GetSysColor(COLOR_MENU)) Else ' here we set the back color of a depressed button hChkBr = CreateSolidBrush(GetSysColor(COLOR_BTNLIGHT)) End If 'Select our new, correctly colored objects: hOldBr = SelectObject(.hDC, hBR) hOldPen = SelectObject(.hDC, hPen) 'Do we have a separator bar? bHasIcon = False sCaption = MenuData(hWndRedirect).Caption If Not IsSep Then ' Ok, does this item have an icon? ' Here we do one more extra check in case the ImageViewer ' is no longer available or has no images (then handle is 0) ' we also set the offset for highlighting rectangle's left ' edge so it doesn't highlight icons If MenuData(hWndRedirect).ImageViewer > 0 And _ MenuData(hWndRedirect).Icon > 0 Then bHasIcon = True iRectOffset = lOffsets(0) - 2 Else 'If bMenuItemChecked Then

47

Page 48: library documentation

' iRectOffset = lOffsets(0) - 2 'Else iRectOffset = lOffsets(1) 'End If End If 'Draw the highlighting rectangle DrawRect .rcItem.Left + iRectOffset, .rcItem.Top, .rcItem.Right, .rcItem.Bottom 'Print the menu item's text If MenuData(hWndRedirect).HotKeyPos Then ' we have a control key, so identify it & its left edge sAccelKey = Mid$(sCaption, MenuData(hWndRedirect).HotKeyPos) sCaption = Left$(sCaption, InStr(sCaption, sAccelKey)) End If ' send the caption, control key, icon offset, etc to be printed tRect = .rcItem DrawCaption .rcItem.Left + lOffsets(0), .rcItem.Top + 3, _ tRect, sCaption, sAccelKey, MenuData(hWndRedirect).HotKeyEdge, lTextColor If bMenuItemDisabled Then ' add the engraved affect tRect = .rcItem ' get starting rectangle & OffsetRect tRect, -1, -1 ' offset by 1 top & left ' print text again with offsets DrawCaption .rcItem.Left + lOffsets(0) - 1, .rcItem.Top + 2, _ tRect, sCaption, sAccelKey, MenuData(hWndRedirect).HotKeyEdge, _ GetSysColor(COLOR_GRAYTEXT) End If If bMenuItemChecked Then ' for checked items, since they can have icons, we do a few ' things different. We make the checked item appear in a sunken ' box and make the backcolor of the box lighter than normal SelectObject .hDC, hChkBr DrawRect lOffsets(1), .rcItem.Top, lOffsets(0) - 5, .rcItem.Bottom - 1 ThreeDbox lOffsets(1) - 2, .rcItem.Top, lOffsets(0) - 3, .rcItem.Bottom - 2, True, True If bHasIcon = False Then ' now if the checked item doesn't have an icon we draw a checkmark in the icons' place DrawCheckMark .rcItem, IIf(bMenuItemDisabled, lTextColor, GetSysColor(COLOR_MENUTEXT)), False, lOffsets(1) If bMenuItemDisabled Then DrawCheckMark .rcItem, GetSysColor(COLOR_GRAYTEXT), bMenuItemDisabled, lOffsets(1) End If End If End If 'If the item has an icon, selected or not, disabled or not If bHasIcon = True Then If bDrawIcon = True Or bMenuItemChecked = True Then ' we are redrawing icons ' extract icon handle, type & transparency option

48

Page 49: library documentation

Dim vIconDat() As Long MenuData(hWndRedirect).GetIconData vIconDat(), MenuData(hWndRedirect).Icon 'set up the location to be drawn tRect.Left = 4 + lOffsets(1) tRect.Top = ((.rcItem.Bottom - .rcItem.Top) - 16) \ 2 + .rcItem.Top tRect.Right = tRect.Left + 16 tRect.Bottom = tRect.Top + 16 'send the icon information to be drawn DrawMenuIcon vIconDat(0), vIconDat(1), tRect, bMenuItemDisabled, True, vIconDat(2) End If SelectObject .hDC, hBR If bMenuItemDisabled = False And bMenuItemChecked = False Then ' here we draw or remove the 3D box around the icon ThreeDbox lOffsets(1), .rcItem.Top, lOffsets(0) - 5, .rcItem.Bottom - 1, bSelected End If End If If IsSep Then 'Finally, draw the special separator bar if needed ' however, if the separator has text, then we need to do ' some additional calculations If Len(sCaption) Then ' separator bars with text SetMenuFont True, , True ' use smaller font tRect = .rcItem ' copy the menuitem coords ' send caption to be printed in menu-select color ' of course any color can be used & if you want to use the ' standard 3D gray disabled color then Rem out the next line ' and un-rem the next 3 lines & the second DrawCapton line DrawCaption .rcItem.Left, .rcItem.Top + 3, tRect, sCaption, "", 0, GetSysColor(COLOR_HIGHLIGHT), True, CInt(lOffsets(1)) 'DrawCaption .rcItem.Left, .rcItem.Top + 3, tRect, sCaption, "", 0, lTextColor, True 'tRect = .rcItem ' recopy menuitem coords 'OffsetRect tRect, -1, -1 ' move coords up & left by 1 ' send caption again in gray 'DrawCaption .rcItem.Left - 1, .rcItem.Top + 2, tRect, sCaption, "", 0, GetSysColor(COLOR_GRAYTEXT), True If bMenuItemChecked = False Then ' here we add the lines on both sides of the separator caption ThreeDbox 4 + lOffsets(1), _ (.rcItem.Bottom - .rcItem.Top) \ 2 + .rcItem.Top, _ tRect.Left - 4, _ (.rcItem.Bottom - .rcItem.Top) \ 2 + 1 + .rcItem.Top, True ThreeDbox tRect.Right + 4, _ (.rcItem.Bottom - .rcItem.Top) \ 2 + .rcItem.Top, _ .rcItem.Right - 4, _ (.rcItem.Bottom - .rcItem.Top) \ 2 + 1 + .rcItem.Top, True

49

Page 50: library documentation

End If Else ' This will remove or add a 3D raised box for checked/non-checked items If bMenuItemChecked = False Then ThreeDbox lOffsets(1) + .rcItem.Left, .rcItem.Top + 2, .rcItem.Right - 4 + lOffsets(1), .rcItem.Bottom - 2, True End If End If 'Select the old objects into the menu's DC Call SelectObject(.hDC, hOldBr) Call SelectObject(.hDC, hOldPen) 'Delete the ones we created Call DeleteObject(hBR) Call DeleteObject(hPen) Call DeleteObject(hChkBr) SetMenuFont False End With CustomDrawMenu = True ' set flag to prevent resending to formCase WM_MEASUREITEM Dim MeasureInfo As MEASUREITEMSTRUCT 'Get the MEASUREITEM info, basically submenu item height/width Call CopyMemory(MeasureInfo, ByVal lParam, Len(MeasureInfo)) ' only process menu items, other windows items send above message ' and we don't want to interfere with those. Also if we didn't ' process it, we don't touch it If MenuData(hWndRedirect).SetMenuID(MeasureInfo.ItemId, lSubMenu, False, False) = False Then Exit Function If MeasureInfo.CtlType <> ODT_MENU Then Exit Function IsSep = (((MenuData(hWndRedirect).Status And 2) = 2) And (Not MenuData(hWndRedirect).Status And 16) = 16) 'Tell Windows how big our items are. ' add height of each item, add a buffer of 3 pixels top/bottom for text MeasureInfo.ItemHeight = MenuData(hWndRedirect).ItemHeight MeasureInfo.ItemWidth = MenuData(hWndRedirect).PanelWidth 'Return the information back to Windows Call CopyMemory(ByVal lParam, MeasureInfo, Len(MeasureInfo)) CustomDrawMenu = TrueCase WM_ENTERIDLE ' done displaying panel, let's stop drawing icons bDrawIcon = FalseEnd SelectEnd Function

Public Function HiWord(LongIn As Long) As Integer' =====================================================================' Returns the high integer of a long variable' =====================================================================

50

Page 51: library documentation

Call CopyMemory(HiWord, ByVal VarPtr(LongIn) + 2, 2)End Function

Public Function LoWord(LongIn As Long) As Integer' =====================================================================' Returns low integer of a long variable' ===================================================================== Call CopyMemory(LoWord, LongIn, 2)End Function

Private Function MakeLong(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long' =====================================================================' Converts 2 integers to a long variable' ===================================================================== MakeLong = CLng(LoWord) Call CopyMemory(ByVal VarPtr(MakeLong) + 2, HiWord, 2)End Function

Private Function DetermineOS(Optional SetGraphicsModeDC As Long = 0) As Integer' Determine OS. Win98, for sure, seems to adjust the menu panel width' to accomodate for the accelerator key within the menu. If the opposite' adjustment isn't made, the panels wind up being wider than desired.' Win98: adjustment needed' Win2K: adjustment not needed' WinNT: adjustment not needed' WinXP: adjustment not needed' Other O/S: ?

' The following are the platform, major version & minor version of OS to date (acquired from MSDN)Const os_Win95 = "1.4.0"Const os_Win98 = "1.4.10"Const os_WinNT4 = "2.4.0"Const os_WinNT351 = "2.3.51"Const os_Win2K = "2.5.0"Const os_WinME = "1.4.90"Const os_WinXP = "2.5.1"

Dim verinfo As OSVERSIONINFO, sVersion As String verinfo.dwOSVersionInfoSize = Len(verinfo)

51

Page 52: library documentation

If (GetVersionEx(verinfo)) = 0 Then Exit Function ' use default 0 With verinfo sVersion = .dwPlatformId & "." & .dwMajorVersion & "." & .dwMinorVersion End With ' those where the iTabOffset is set are systems that I have seen the ' results on; otherwise, assume no adjustment is necessary Select Case sVersion Case os_Win98: iTabOffset = 32 Case os_Win2K: iTabOffset = 0 Case os_WinNT4: iTabOffset = 0 Case os_WinNT351 ' Problems when printing rotated text 'According to MSDN, NT 3.51 only works on a setting of 2. Don't have the opportunity to test this. SetGraphicsMode SetGraphicsModeDC, 2 Case os_Win95 Case os_WinXP: iTabOffset = 0 Case os_WinME End SelectEnd Function

Public Function GetFormHandle(hwnd As Long, Optional bIsMDI As Boolean) As LongDim i As LongFor i = Forms.Count - 1 To 0 Step -1 If Forms(i).hwnd = hwnd Then Exit ForNextIf i > -1 Then If TypeOf Forms(i) Is MDIForm Then bIsMDI = True GetFormHandle = iEnd IfEnd Function

Private Sub ReadMe()'HOW TO USE THIS CLASS AND MODULES

'1. Each form that is subclassing menus must have the 2 lines of code entered into the events shown below. The imagelist'name is optional and must be provided if icons are to be displayed. Any loaded form's imagelist can be used.

' MDI forms: If you are using MDI forms, if a child or parent is being subclassed,' you must subclass each child and the parent. Additionally, the MDI children use the' imagelist on the MDI form and MDI children do not reference the imagelist when' the SetMenus command is called. All subclassed forms call the ReleaseMenus on form unload.

' a. Form_Load: the last statement in this event should be: SetMenus [form handle (.hWnd)] , [ImageList Name for Icons]

52

Page 53: library documentation

' -- for MDI children: SetMenus [form handle (.hWnd)] << uses the parent MDI form's imagelist' b. Form_Unload: the 1st statement in this event should be: ReleaseMenus [form handle (.hWnd)]

'Example: SetMenus Me.hWnd, ImageList1

'2. DO NOT place breaks in the code when menus are subclassed or stop the code when menus are subclassed.'Doing so will crash VB. If you need to debug your code, set the public constant bAmDebugging=True within the'modModules module. This will prevent menus from being subclassed and will also prevent menus from displaying icons.'Be sure to set that constant = False when you want to see the icons.

'3. Do not put END statements in any of the forms that are subclassing menus. The End statement may fire before'the menus are released which will cause a critical error. The class and modules are written to release themselves'via the ReleaseMenus command.

'4. Assigning icons/bitmaps to your submenu items.

' a. Suggestion: Small icons (16x16) are best as far as clarity goes' b. Suggeston: If bitmaps are used, use smaller bitmaps (16x16) vs larger bitmaps (32x32)' c. Add the following flag immediately in front of the menu's caption: {IMG:#}' d. The # is the listimage icon index (1 thru n)' e. If you want to supply a manually trapped accelerator key add that to the end of the menu caption. See para 6. ' Example: menu caption is E&xit and image number 2 will be assigned to it and Alt+F4 will be the' manually trapped accelerator key

' {IMG:2}E&xit Alt+F4

'5. Optional transparency flag. By default, icons are NOT made to be transparent since they probably are anyway.'However, bitmaps by default ARE made to be transparentt. When transparency is invoked, the top left pixel'decides which color is made transparent throughout the image. Should you want to force an icon/bitmap to'be transparent or not be transparent, add the following code after the icon index in the caption header flag: ' |N to prevent transparency or |Y to force transparency

' Example: I have a bitmap in the imagelist which has a colored background that I do NOT want made transparent.

53

Page 54: library documentation

' Being a bitmap, by default, it will be made transparent. So I need to add then |N option to the menu caption:

' {IMG:3|N}CD &Player Alt+P

'6. Accelerator keys. The menu builder allows you to select many accelerator keys and will automatically trap them for you.'With this class & modules you can add other accelerator keys not provided by the menu builder (i.e., Alt+F4) and you'can use the same accelerator key on more than one menu -- not allowed via the menu builder.

' a. If you add an accelerator key manually (not via menu builder), you will need to trap those keys in the form's Key_Down' event by testing for KeyCode and Shift values

' b. In the examples above, manually adding an accelerator key is as simple as placing it at the end of the caption.

' c. The modules will align the accelerator keys neatly before they are displayed on the menu.

'7. To change the caption or image of a menu after the program is running, simply change it in VB via the Caption property.'The module will recognize the change and change the caption and/or assign the new icon. If you want to remove the icon'from the menu caption, do not include the {IMG:#} header or make the icon index = zero. Note. The menu caption when'referenced in VB will have the {IMG:#} header in the caption, but is stripped off when displaying the menu.

' Example: Change {IMG:5}Color Option is On to read Off whle using the same icon' Changet to: {IMG:5}Color Option is Off << that's it!

'8. Checkmarks and enabled/disabled menu items. The modules will draw a sunken box for menu items that are'checked and include the icon inside the sunken box, if one is assigned; otherwise a checkmark is placed inside' the sunken box. Disabled menu items are made to imitate regular disabled items to include the icon and caption.

'9. Separator bars. You can add text to the separator bars. While in the menu builder, include the hyphen/dash to'designate the menu item as a separator and then add the text immediately after. {IMG:#} headers will not be'recognized on separators, nor will accelerator keys be spaced with other accelerator keys. Separator bars,'regardless if they have text or not, are not clickable.

54

Page 55: library documentation

' a. By default, text on separator bars are one font point lower than the system menu font and a font type of Tahoma.

' b. The color of the text on the separator will be the same color as the color used to highlight a menu item with the mouse.

' c. If the bAmDebugging flag is set to True, then the separator bars will not be disabled. Nor will they look disabled.

'10. These modules do not interfere with any menu events (i.e., click events, popup position, etc, etc, etc are not affected)

'11. These modules to not draw parent level menus. In other words, menus that have submenus are not drawn by the'modules -- but their submenus are. The class and modules were written to use Windows default menu style but add'the capability of icons to submenus. Therefore, foreground colors, fonts and background colors are not supported'as this would not mirror the parent level menu items.

'12. The basic premis. Provide a somewhat small class and modules that can be added to any project to support'icons and make the subclassing easy. Other projects available on the web will draw entire menus but come at'a price -- large number of classes and modules added to each project or forcing DLLs on other users.

'13. Sidebars. These are bitmaps or text along the left edge of a menu panel.'You can add a picture or text by following these format rules. The images on'a sidebar will be shrunk to fit if necessary, otherwise centered into the sidebar.'When images are shrunk, they are done proportionally, therefore, there may be'space around the image within the sidebar. If the formatted string is incorrect,'no sidebar will be shown.

'That menu item MUST be visible, otherwise no sidebar will be drawn

'On any submenu of a menu, add the following formatted string'Don't use spaces. Spaces below done for readability

' a. For images in controls like image controls, pictureboxes, etc:

' {SIDEBAR:control | BCOLOR:color }' Example: {SIDEBAR:image1|BCOLOR:background}

' b. For images passed as handles. You must provide much more information' {SIDEBAR:handle | BCOLOR:color }' (SIDEBAR:120928|BCOLOR:background}

' The values for the tags in the above strings are as follows:' If image is passed as a control, then the following is mandatory

55

Page 56: library documentation

' control: This is the control name with a picture property' and must exist on the same form that is subclassing menus' This also applies to MDI parents and children' color: optional. Default is NONE. The color is used to fill in the space' between the image and the sidebar when the image doesn't completely' fill up the sidebar. Values for Color can be...' 1. The numerical value of a color (i.e., BCOLOR:65535)' 2. NONE. This will not fill in the space between image and sidebar' 3. BACKGROUND. This will fill the space with the images top left pixel color' If image is passed as a handle vs a form control, then this is mandatory:' handle: the numerical picture.handle should be a bitmap! Icons will draw at 16x16

' c. For Text: don't use spaces except in the caption if needed. Spaces below done for readability' {SIDEBAR:TEXT | CAPTION:caption | FONT:fontname | FCOLOR:color | BCOLOR:color | FSIZE:font_size}' Optional flags can be added by preceding them with a pipe |' BOLD, ITALIC, UNDERLINE, GRADIENT' Example: {SIDEBAR:TEXT|CAPTION:La Volpe|FONT:Algerian|FCOLOR:16777215|BCOLOR:255|FSIZE:12|GRADIENT}

' The values for the tags in the above string are as follows:

' caption: mandatory. The text you want displayed on the sidebar. The text font size will be' be 11 by default but reduced to fit the sidebar if needed' fontname: Optional. The font to use. This font should be scalable. In other words,' if the font size can be set as an odd number then don't use it.' The default font will be Tahoma' forecolor color: optional. Numerical value for the color of the text. Default is black' backcolor color: optional. Numerical value for the back color of the sidebar. Default is menu color' font_size: optional. Whole number of a font size. Default is 11' BOLD: optional. If supplied, font is bolded. Default is no bolding' ITALIC: optional. If supplied, font is italicized. Default is no italics' UNDERLINE: optional. If supplied, font is underlined. Default is no underlining' GRADIENT: optional. If supplied, it is the word GRADIENT and will color the sidebar' in the backcolor, from black to backcolor, bottom to top.

'Suggestions? I will entertain any suggestions (always have). However, I do not plan on making this class draw'entire menus. I thought of the possibility of having icons & bitmaps on menus that are not loaded into an'imagelist. However, I don't immediately see why that would be necessary. If you have a need for that'capability, let me know -- I have already ran test code to make that happen.End Sub

56

Page 57: library documentation

57

Page 58: library documentation

Program coding with visual shots

Login page

58

Page 59: library documentation

This feature is advanced security control. Each user have separate account with user name and password Three wrong entries of user name and password exits the program aumatically

Program coding for login

Dim pwctr As Integer

Private Sub cmdCancel_Click()ReleaseMenus hwndEndEnd Sub

Private Sub cmdOK_Click()

Set userRS = New ADODB.RecordsetIf txtUserName.Text <> "" Then SQLstr = "Select * From userlist Where username = '" & Trim(txtUserName.Text) & "'" userRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If txtUserName.Text <> "Administrator" Then If txtUserName.Text <> "administrator" Then If txtUserName.Text <> "ADMINISTRATOR" Then frmmain.mnusettingsystem.Enabled = False frmmain.mnusettinguser.Enabled = False Else frmmain.mnusettingsystem.Enabled = True frmmain.mnusettinguser.Enabled = True End If Else frmmain.mnusettingsystem.Enabled = True frmmain.mnusettinguser.Enabled = True End If Else frmmain.mnusettingsystem.Enabled = True frmmain.mnusettinguser.Enabled = True End If If Not userRS.EOF And Not userRS.BOF Then

59

Page 60: library documentation

If txtPassword.Text <> userRS!Password Then pwctr = pwctr + 1 If pwctr = 1 Then MsgBox "Invalid password! You have 2 tries remaining!", vbOKOnly + vbInformation, "Information" txtPassword.Text = "" txtPassword.SetFocus ElseIf pwctr = 2 Then MsgBox "Invalid password! You only have 1 try remaining!", vbOKOnly + vbInformation, "Information" txtPassword.Text = "" txtPassword.SetFocus Else ReleaseMenus hwnd End End If Else Unload Me frmmain.Show End If Else MsgBox "Invalid Username!", vbOKOnly + vbExclamation, "Warning.." txtUserName.Text = "" txtPassword.Text = "" txtUserName.SetFocus End IfElse MsgBox "Invalid Username and Password!", vbOKOnly + vbExclamation, "Warning.." txtUserName.SetFocusEnd If

End Sub

Private Sub Form_Load() dbconnect txtUserName.Text = GetSetting(App.EXEName, "TextBox", txtUserName.Name, "")End Sub

Private Sub Form_Unload(Cancel As Integer) SaveSetting App.EXEName, "Textbox", txtUserName.Name, txtUserName.TextEnd Sub

Private Sub txtPassword_KeyPress(KeyAscii As Integer)If KeyAscii = 13 Then If cmdOK.Enabled = True Then cmdOK.Value = True End If

60

Page 61: library documentation

End IfEnd Sub

Private Sub txtUserName_KeyPress(KeyAscii As Integer)If KeyAscii = 13 Then txtPassword.SetFocusEnd IfEnd Sub

Main page

61

Page 62: library documentation

Program coding for main page

'this code is exit button to prompt a message box b4 exitingPrivate Const clMsgbxEXITAPP As Long = vbDefaultButton1 + vbQuestion + vbYesNoPrivate mbIsDirty As Boolean

Private Sub Form_Load() dbconnect SetMenus hwnd, ImageList1 'this code is exit button to prompt a message box b4 exiting Debug.Print "Form1::Load" mbIsDirty = TrueEnd Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)'this code is exit button to prompt a message box b4 exiting Debug.Print "Form1::QueryUnload" If mbIsDirty Then Cancel = CInt(pExitApp = False) If Not Cancel Then '-- We are ending the app. Clean up here. Debug.Print "Clean Up time..." Dim F As VB.Form For Each F In Forms Unload F Next ReleaseMenus hwnd End If End IfEnd Sub

Private Function pExitApp() As Boolean

62

Page 63: library documentation

'this code is exit button to prompt a message box b4 exiting Debug.Print "Exit Application" pExitApp = (MsgBox("Exit system?", clMsgbxEXITAPP, "Library") = vbYes)End Function

Private Sub Form_Unload(Cancel As Integer)'this code is exit button to prompt a message box b4 exiting Debug.Print "Form1::Unload"End Sub

Private Sub mnuabout_Click()frmAbout.Show vbModalEnd Sub

Private Sub mnufilebook_Click() frmbookcatalog.Show vbModalEnd Sub

Private Sub mnufileborrowerstud_Click()

End Sub

Private Sub mnufileborrower_Click() frmborrower.Show vbModalEnd Sub

Private Sub mnufileexit_Click()If MsgBox("Exit system?", vbQuestion + vbYesNo) = vbNo Then Exit SubEnd IfReleaseMenus hwndEndEnd Sub

Private Sub mnufilefind_Click() frmfind.Show vbModalEnd Sub

Private Sub mnureportsbook_Click() Set bookRS = New ADODB.Recordset bookRS.Open "book_catalog", libCON, adOpenKeyset, adLockReadOnly Set rptbook.DataSource = bookRS rptbook.Show vbModalEnd Sub

Private Sub mnureportsborrow_Click() Set borrowerRS = New ADODB.Recordset borrowerRS.Open "borrower_record", libCON, adOpenKeyset, adLockReadOnly Set rptborrower.DataSource = borrowerRS rptborrower.Show vbModal

63

Page 64: library documentation

End Sub

Private Sub mnureportscurrent_Click() Set currentRS = New ADODB.Recordset currentRS.Open "current_borrow", libCON, adOpenKeyset, adLockReadOnly Set rptcurrent.DataSource = currentRS rptcurrent.ShowEnd Sub

Private Sub mnureportsdue_Click() Set currentRS = New ADODB.Recordset SQLstr = "select * from current_borrow where due_date = date()" currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly Set rptdue.DataSource = currentRS rptdue.Show vbModalEnd Sub

Private Sub mnureportsover_Click() Set currentRS = New ADODB.Recordset SQLstr = "select * from current_borrow where due_date < date()" currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly Set rptoverdue.DataSource = currentRS rptoverdue.Show vbModalEnd Sub

Private Sub mnusettingsystemcategory_Click() frmcategory.Show vbModalEnd Sub

Private Sub mnusettingsystemcourse_Click() frmcourse.Show vbModalEnd Sub

Private Sub mnusettingsystemfee_Click() frmsystem.Show vbModalEnd Sub

Private Sub mnusettinguser_Click() frmusers.Show vbModalEnd Sub

Private Sub mnutransborrow_Click() frmborrowing.Show vbModalEnd Sub

Private Sub mnutransreturn_Click() frmreturning.Show vbModalEnd Sub

Book catalog

64

Page 65: library documentation

Program coding for book catalog

Dim x, y As Integer

Private Sub clear() Combo1.Text = "" Text1.Text = "" Text2.Text = "" Text3.Text = "" Text4.Text = "" Text5.Text = "" Combo2.Text = "" Combo3.Text = ""End Sub

Private Sub disable() Combo1.Enabled = False Text1.Enabled = False Text2.Enabled = False Text3.Enabled = False Text4.Enabled = False Text5.Enabled = False Combo2.Enabled = False Combo3.Enabled = FalseEnd Sub

Private Sub enable() Combo1.Enabled = True Text1.Enabled = True Text2.Enabled = True

65

Page 66: library documentation

Text3.Enabled = True Text4.Enabled = True Text5.Enabled = True Combo2.Enabled = True Combo3.Enabled = TrueEnd Sub

Private Sub Command1_Click() enable Text1.SetFocus Command1.Enabled = False Command2.Enabled = True Command5.Enabled = False Command6.Caption = "&CANCEL"End Sub

Private Sub Command2_Click()If Text1.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text1.SetFocus Exit SubEnd IfIf Combo1.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Combo1.SetFocus Exit SubEnd IfIf Text2.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text2.SetFocus Exit SubEnd IfIf Text5.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text5.SetFocus Exit SubEnd IfIf Text3.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text3.SetFocus Exit SubEnd IfIf Text4.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text4.SetFocus Exit SubEnd IfIf Combo2.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Combo2.SetFocus

66

Page 67: library documentation

Exit SubEnd IfIf Combo3.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Combo3.SetFocus Exit SubEnd If

If Command2.Caption = "&SAVE" Then Set bookRS = New ADODB.Recordset SQLstr = "select access_no from book_catalog where access_no='" & Text1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If Not bookRS.EOF And Not bookRS.BOF Then MsgBox "Accession No. already exist!", vbExclamation Text1.SetFocus Exit SubEnd If If MsgBox("Save Book Catalog?", vbYesNo + vbQuestion) = vbYes Then Set bookRS = New ADODB.Recordset bookRS.Open "book_catalog", libCON, adOpenKeyset, adLockOptimistic With bookRS .AddNew !access_no = Text1.Text !category = Combo1.Text !Title = Text2.Text !Edition = Text5.Text !Author = Text3.Text !Publisher = Text4.Text !yr_publish = Combo3.Text !no_copy = Combo2.Text !available_copy = Combo2.Text .Update .Close End With MsgBox "Book Catalog Successfully Saved!", vbInformation End IfElse If MsgBox("Update Book Catalog?", vbYesNo + vbQuestion) = vbYes Then Set bookRS = New ADODB.Recordset SQLstr = "Select * from book_catalog where access_no='" & Text1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockOptimistic With bookRS !category = Combo1.Text !Title = Text2.Text !Edition = Text5.Text !Author = Text3.Text !Publisher = Text4.Text !yr_publish = Combo3.Text !no_copy = Combo2.Text

67

Page 68: library documentation

!available_copy = Combo2.Text .Update .Close End With MsgBox "Book Catalog Successfully Updated!", vbInformation End IfEnd If clear disable Command1.Enabled = True Command2.Enabled = False Command2.Caption = "&SAVE" Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE"End Sub

Private Sub Command3_Click() enable Text1.Enabled = False Combo1.SetFocus Command2.Enabled = True Command2.Caption = "&UPDATE" Command3.Enabled = False Command4.Enabled = False Command7.Visible = FalseEnd Sub

Private Sub Command4_Click() If MsgBox("Sure To Delete Book Catalog?", vbQuestion + vbYesNo) = vbYes Then Set bookCMD = New ADODB.Command SQLstr = "Delete * from book_catalog where access_no='" & Text1.Text & "'" With bookCMD .ActiveConnection = libCON .CommandType = adCmdText .CommandText = SQLstr .Execute End With clear MsgBox "Book Catalog Successfully Deleted!", vbInformation Command1.Enabled = True Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE"

68

Page 69: library documentation

Command7.Visible = False End IfEnd Sub

Private Sub Command5_Click() Text1.Enabled = True Text1.SetFocus Command1.Enabled = False Command5.Enabled = False Command6.Caption = "&CANCEL" Command7.Visible = TrueEnd Sub

Private Sub Command6_Click() If Command6.Caption = "CL&OSE" Then Unload Me Else clear disable Command1.Enabled = True Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE" Command7.Visible = False End IfEnd Sub

Private Sub Command7_Click() Set bookRS = New ADODB.Recordset SQLstr = "Select * from book_catalog where access_no='" & Text1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If bookRS.EOF And bookRS.BOF Then MsgBox "Accession Number Not Found!", vbExclamation Text1.SetFocus Exit Sub End If With bookRS Combo1.Text = !category Text2.Text = !Title Text3.Text = !Author Text4.Text = !Publisher Text5.Text = !Edition Combo2.Text = !no_copy Combo3.Text = !yr_publish End With Command3.Enabled = True Command4.Enabled = TrueEnd Sub

69

Page 70: library documentation

Private Sub Form_Load() dbconnect clear disable Set catRS = New ADODB.Recordset catRS.Open "category", libCON, adOpenKeyset, adLockReadOnly While catRS.EOF <> True Combo1.AddItem catRS!category catRS.MoveNext Wend x = 1 While x <= 10 Combo2.AddItem x x = x + 1 Wend y = 1601 While y <= 9999 Combo3.AddItem y y = y + 1 Wend Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command7.Visible = FalseEnd Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)If Command7.Visible = True Then If KeyAscii = 13 Then Command7.Value = True End IfEnd IfEnd Sub

70

Page 71: library documentation

Borrowers record

Program coding for borrower’s recordPrivate Sub clear() Text5.Text = "" Text1.Text = "" Text2.Text = "" Text3.Text = "" Option1.Value = False Option2.Value = False Combo1.Text = "" Text4.Text = "" MaskEdBox2.Text = "( ) - "End Sub

Private Sub disable() Text5.Enabled = False Text1.Enabled = False Text2.Enabled = False Text3.Enabled = False Option1.Enabled = False Option2.Enabled = False Text4.Enabled = False Combo1.Enabled = False MaskEdBox2.Enabled = FalseEnd Sub

Private Sub enable() Text5.Enabled = True

71

Page 72: library documentation

Text1.Enabled = True Text2.Enabled = True Text3.Enabled = True Option1.Enabled = True Option2.Enabled = True Text4.Enabled = True 'Combo1.Enabled = True MaskEdBox2.Enabled = TrueEnd Sub

Private Sub Command1_Click() enable Text5.SetFocus Command1.Enabled = False Command2.Enabled = True Command5.Enabled = False Command6.Caption = "&CANCEL"End Sub

Private Sub Command2_Click()If Text5.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text5.SetFocus Exit SubEnd IfIf Text1.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text1.SetFocus Exit SubEnd IfIf Text2.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text2.SetFocus Exit SubEnd IfIf Text3.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text3.SetFocus Exit SubEnd IfIf Option1.Value = False And Option2.Value = False Then MsgBox "Complete neccessary information", vbExclamation Option1.SetFocus Exit SubEnd IfIf Option1.Value = True And Combo1.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Combo1.SetFocus Exit SubEnd If

72

Page 73: library documentation

If Text4.Text = "" Then MsgBox "Complete neccessary information", vbExclamation Text4.SetFocus Exit SubEnd If If Command2.Caption = "&SAVE" Then Set borrowerRS = New ADODB.Recordset SQLstr = "select borrower_id from borrower_record where borrower_id='" & Text5.Text & "'" borrowerRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If Not borrowerRS.EOF And Not borrowerRS.BOF Then MsgBox "Borrower ID already exist!", vbExclamation Text5.SetFocus Exit Sub End If If MsgBox("Save Borrower Record?", vbYesNo + vbQuestion) = vbYes Then Set borrowerRS = New ADODB.Recordset borrowerRS.Open "borrower_record", libCON, adOpenKeyset, adLockOptimistic With borrowerRS .AddNew !borrower_id = Text5.Text !lname = Text1.Text !fname = Text2.Text !mI = Text3.Text If Option1.Value = True Then !Status = "Student" Else !Status = "Faculty / Employee" End If !course = Combo1.Text !Add = Text4.Text !contact = MaskEdBox2.Text .Update .Close End With MsgBox "Borrower Record Successfully Saved!", vbInformation End IfElse If MsgBox("Update Borrower Record?", vbYesNo + vbQuestion) = vbYes Then Set borrowerRS = New ADODB.Recordset SQLstr = "Select * from borrower_record where borrower_id='" & Text5.Text & "'" borrowerRS.Open SQLstr, libCON, adOpenKeyset, adLockOptimistic With borrowerRS !lname = Text1.Text !fname = Text2.Text !mI = Text3.Text

73

Page 74: library documentation

If Option1.Value = True Then !Status = "Student" Else !Status = "Faculty / Employee" End If !course = Combo1.Text !Add = Text4.Text !contact = MaskEdBox2.Text .Update .Close End With MsgBox "Borrower Record Successfully Updated!", vbInformation End IfEnd If

clear disable Command1.Enabled = True Command2.Enabled = False Command2.Caption = "&SAVE" Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE"End Sub

Private Sub Command3_Click() enable Text5.Enabled = False Text1.SetFocus Combo1.Enabled = True Command2.Enabled = True Command2.Caption = "&UPDATE" Command3.Enabled = False Command4.Enabled = False Command7.Visible = FalseEnd Sub

Private Sub Command4_Click() If MsgBox("Sure To Delete Borrower Record?", vbQuestion + vbYesNo) = vbYes Then Set borrowerCMD = New ADODB.Command SQLstr = "Delete * from borrower_record where borrower_id='" & Text5.Text & "'" With borrowerCMD .ActiveConnection = libCON .CommandType = adCmdText .CommandText = SQLstr .Execute End With

74

Page 75: library documentation

clear MsgBox "Borrower Record Successfully Deleted!", vbInformation Command1.Enabled = True Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE" Command7.Visible = False End IfEnd Sub

Private Sub Command5_Click() Text5.Enabled = True Text5.SetFocus Command1.Enabled = False Command5.Enabled = False Command6.Caption = "&CANCEL" Command7.Visible = TrueEnd Sub

Private Sub Command6_Click() If Command6.Caption = "CL&OSE" Then Unload Me Else clear disable Command1.Enabled = True Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command5.Enabled = True Command6.Caption = "CL&OSE" Command7.Visible = False End IfEnd Sub

Private Sub Command7_Click() Set borrowerRS = New ADODB.Recordset SQLstr = "Select * from borrower_record where borrower_id='" & Text5.Text & "'" borrowerRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If borrowerRS.EOF And borrowerRS.BOF Then MsgBox "Borrower ID not valid!", vbExclamation Text5.SetFocus Exit Sub End If With borrowerRS

75

Page 76: library documentation

Text1.Text = !lname Text2.Text = !fname Text3.Text = !mI If !Status = "Student" Then Option1.Value = True Else Option2.Value = True End If Combo1.Text = !course Text4.Text = !Add MaskEdBox2.Text = !contact End With Command3.Enabled = True Command4.Enabled = TrueEnd Sub

Private Sub Form_Load() dbconnect clear disable Set courseRS = New ADODB.Recordset courseRS.Open "course", libCON, adOpenKeyset, adLockReadOnly While courseRS.EOF <> True Combo1.AddItem courseRS!course courseRS.MoveNext Wend Command2.Enabled = False Command3.Enabled = False Command4.Enabled = False Command7.Visible = FalseEnd Sub

Private Sub Option1_Click()If Option1.Enabled = True Then Combo1.Enabled = True Combo1.Text = ""End IfEnd Sub

Private Sub Option2_Click()If Option2.Enabled = True Then Combo1.Enabled = False Combo1.Text = "n/a"End IfEnd Sub

Private Sub Text5_KeyPress(KeyAscii As Integer)

76

Page 77: library documentation

If Command7.Visible = True Then If KeyAscii = 13 Then Command7.Value = True End IfEnd IfEnd Sub

Finding books

This is an icon which is used to find the input data by clicking on it.

Program coding for finding of books

Private Sub SetListViewTo(ByVal xrs As ADODB.Recordset, Optional ByVal strSMIcons As String = "", Optional ByVal strLRGIcons As String = "", Optional ByVal clmWidth)ListView1.ListItems.clearxrs.MoveFirstWhile Not xrs.EOF Set Item = ListView1.ListItems.Add(, "_" & xrs.Fields(0).Value, xrs.Fields(0).Value) 'Item.SubItems(1) = xrs!access_no Item.SubItems(1) = xrs!Title Item.SubItems(2) = xrs!Edition Item.SubItems(3) = xrs!Author Item.SubItems(4) = xrs!Publisher Item.SubItems(5) = xrs!yr_publish Item.SubItems(6) = xrs!no_copy Item.SubItems(7) = xrs!available_copy

77

Page 78: library documentation

Item.SubItems(8) = xrs!borrow_copy xrs.MoveNextWendEnd Sub

Public Sub SetSectionViewTitle() Set bookRS = New ADODB.Recordset SQLstr = "SELECT * FROM book_catalog WHERE title='" & Text1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If bookRS.EOF And bookRS.BOF Then MsgBox "No title found!", vbInformation Exit Sub End If SetListViewTo bookRS, 2, 2, clmWidth End Sub

Public Sub SetSectionViewAuthor() Set bookRS = New ADODB.Recordset SQLstr = "SELECT * FROM book_catalog WHERE author='" & Text1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If bookRS.EOF And bookRS.BOF Then MsgBox "No Author found!", vbInformation Exit Sub End If SetListViewTo bookRS, 2, 2, clmWidthEnd Sub

Private Sub Command1_Click() If Option1.Value = True Then SetSectionViewTitle Else SetSectionViewAuthor End IfEnd Sub

Private Sub Command2_Click() Unload MeEnd Sub

Private Sub Form_Load() Option1.Value = TrueEnd Sub

Private Sub Option1_Click()

78

Page 79: library documentation

If Option1.Value = True Then Label1.Caption = "Search by Title :" End IfEnd Sub

Private Sub Option2_Click() If Option2.Value = True Then Label1.Caption = "Search by Author :" End IfEnd Sub

Private Sub Text1_Change()ListView1.ListItems.clearEnd Sub

Borrowing of books

This is a command button which is used to borrow the books by entering the borrower id. Automatically name and status will be displayed

In the books information type the accestion no of book which you want to borrow.

79

Page 80: library documentation

By clicking save command button library transaction successfully saved.

Program coding for borrowing of books

Dim xcat, xedition, xauthor, xpublisher, xyr_publish As StringDim xavail_copy As Integer

Private Sub SetListViewTo(ByVal xrs As ADODB.Recordset, Optional ByVal strSMIcons As String = "", Optional ByVal strLRGIcons As String = "", Optional ByVal clmWidth)ListView1.ListItems.clearxrs.MoveFirstWhile Not xrs.EOF Set Item = ListView1.ListItems.Add(, "_" & xrs.Fields(0).Value, xrs.Fields(0).Value) Item.SubItems(1) = xrs!access_no Item.SubItems(2) = xrs!Title Item.SubItems(3) = xrs!Edition Item.SubItems(4) = xrs!Author Item.SubItems(5) = xrs!Publisher Item.SubItems(6) = xrs!yr_publish xrs.MoveNextWendEnd Sub

Public Sub SetSectionView() Set currentRS = New ADODB.Recordset SQLstr = "SELECT * FROM current_borrow WHERE borrower_id='" & Text1.Text & "'" currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If currentRS.EOF And currentRS.BOF Then Exit Sub End If

80

Page 81: library documentation

SetListViewTo currentRS, 2, 2, clmWidthEnd Sub

Private Sub clear() Text1.Text = "" Text2.Text = "" Text3.Text = "" Text4.Text = "" Combo1.Text = "" DTPicker1.Value = DateEnd Sub

Private Sub disable() Text1.Enabled = False Text2.Enabled = False Text3.Enabled = False Text4.Enabled = False Combo1.Enabled = False DTPicker1.Enabled = FalseEnd Sub

Private Sub Combo1_Change()Dim strPart As String, iLoop As Integer, iStart As Integer, strItem As String If Not auto And Combo1.Text <> "" Then iStart = Combo1.SelStart strPart = Left$(Combo1.Text, iStart) For iLoop = 0 To Combo1.ListCount - 1 strItem = UCase$(Combo1.List(iLoop)) If strItem Like UCase$(strPart & "*") And strItem <> UCase$(Combo1.Text) Then auto = True Combo1.SelText = Mid$(Combo1.List(iLoop), iStart + 1) Combo1.SelStart = iStart Combo1.SelLength = Len(Combo1.Text) - iStart auto = False Exit For End If Next iLoop End If

If Combo1.Text = "" Then Text4.Text = "" xcat = "" xedition = "" xauthor = "" xpublisher = "" xyr_publish = ""End IfIf Combo1.Text <> "" And Text4.Text <> "" Then Command2.Enabled = True

81

Page 82: library documentation

Else Command2.Enabled = FalseEnd IfEnd Sub

Private Sub Combo1_Click() Set bookRS = New ADODB.Recordset SQLstr = "Select * from book_catalog where access_no='" & Combo1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly With bookRS Text4.Text = !Title xcat = !category xedition = !Edition xauthor = !Author xpublisher = !Publisher xyr_publish = !yr_publish xavail_copy = !available_copy End With If Combo1.Text <> "" And Text4.Text <> "" Then Command2.Enabled = TrueElse Command2.Enabled = FalseEnd IfEnd Sub

Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer) If KeyCode = vbKeyBack Or KeyCode = vbKeyDelete Then auto = True Combo1.SelText = "" auto = False ElseIf KeyCode = vbKeyReturn Then Combo1_LostFocus Combo1.SelStart = Len(Combo1.Text) End IfEnd Sub

Private Sub Combo1_KeyPress(KeyAscii As Integer)If KeyAscii = 13 Then Set bookRS = New ADODB.Recordset SQLstr = "Select * from book_catalog where access_no='" & Combo1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If bookRS.EOF And bookRS.BOF Then Exit Sub End If With bookRS Text4.Text = !Title xcat = !category xedition = !Edition xauthor = !Author

82

Page 83: library documentation

xpublisher = !Publisher xyr_publish = !yr_publish xavail_copy = !available_copy End With If Combo1.Text <> "" And Text4.Text <> "" Then Command2.Enabled = True Else Command2.Enabled = False End IfEnd IfEnd Sub

Private Sub Combo1_LostFocus()Dim iLoop As Integer If Combo1.Text <> "" Then For iLoop = 0 To Combo1.ListCount - 1 If UCase$(Combo1.List(iLoop)) = UCase$(Combo1.Text) Then auto = True Combo1.Text = Combo1.List(iLoop) auto = False Exit For End If Next iLoop End IfEnd Sub

Private Sub Command1_Click() Text1.Enabled = True Text1.SetFocus Command1.Enabled = False Command6.Caption = "&CANCEL" Command7.Visible = TrueEnd Sub

Private Sub Command3_Click() Text1.Enabled = False Command7.Visible = False frmaddbook.Show vbModalEnd Sub

Private Sub Command2_Click() If xavail_copy = 0 Then MsgBox "There is no available copy of this book!", vbInformation Combo1.SetFocus Exit Sub End If Set currentRS = New ADODB.Recordset

83

Page 84: library documentation

SQLstr = "Select * from current_borrow where access_no='" & Combo1.Text & "'" & " and borrower_id='" & Text1.Text & "'" currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If Not currentRS.EOF And Not currentRS.BOF Then MsgBox "Borrower's cannot borrow 2 same book title!", vbInformation Combo1.SetFocus Exit Sub End If Set currentRS = New ADODB.Recordset currentRS.Open "current_borrow", libCON, adOpenKeyset, adLockOptimistic With currentRS .AddNew !access_no = Combo1.Text !Title = Text4.Text !category = xcat !Edition = xedition !Author = xauthor !Publisher = xpublisher !yr_publish = xyr_publish !borrow_date = Label4.Caption If DTPicker1.Enabled = True Then !due_date = DTPicker1.Value End If !borrower_id = Text1.Text !Name = Text2.Text !Status = Text3.Text .Update .Close End With Set bookRS = New ADODB.Recordset SQLstr = "select * from book_catalog where access_no='" & Combo1.Text & "'" bookRS.Open SQLstr, libCON, adOpenKeyset, adLockOptimistic With bookRS !available_copy = xavail_copy - 1 !borrow_copy = !borrow_copy + 1 .Update .Close End With

SetSectionView MsgBox "Library Transaction Successfully Saved!", vbInformation If ListView1.ListItems.Count = 3 Then 'MsgBox "Borrower reach the maximum book that can be borrowed at a time!", vbExclamation clear disable ListView1.ListItems.clear

84

Page 85: library documentation

Command1.Enabled = True Command2.Enabled = False Command6.Caption = "CL&OSE" Exit Sub End If If MsgBox("Borrow Another Book?", vbQuestion + vbYesNo) = vbYes Then Combo1.Text = "" Combo1.SetFocus Exit Sub End If clear disable ListView1.ListItems.clear Command1.Enabled = True Command2.Enabled = False Command6.Caption = "CL&OSE"End Sub

Private Sub Command6_Click()If Command6.Caption = "CL&OSE" Then Unload MeElse clear disable Command1.Enabled = True Command2.Enabled = False Command6.Caption = "CL&OSE" Command7.Visible = FalseEnd IfEnd Sub

Private Sub Command7_Click() Set borrowerRS = New ADODB.Recordset SQLstr = "Select * from borrower_record where borrower_id='" & Text1.Text & "'" borrowerRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly If borrowerRS.EOF And borrowerRS.BOF Then MsgBox "Borrower ID not valid!", vbExclamation Text1.SetFocus Exit Sub End If With borrowerRS Text2.Text = !lname & ", " & !fname & " " & !mI Text3.Text = !Status End With SetSectionView If ListView1.ListItems.Count = 3 Then MsgBox "Borrower Already Borrowed 3 Books!", vbExclamation

85

Page 86: library documentation

clear ListView1.ListItems.clear Text1.Text = "" Text1.SetFocus Exit Sub End If If Text3.Text = "Faculty / Employee" Then DTPicker1.Enabled = False Else DTPicker1.Enabled = True End If Combo1.Enabled = True Combo1.SetFocus Text1.Enabled = False Command7.Visible = FalseEnd Sub

Private Sub Form_Load() dbconnect clear disable Label4.Caption = Date Command2.Enabled = False Command7.Visible = False

'accession number Set bookRS = New ADODB.Recordset bookRS.Open "book_catalog", libCON, adOpenKeyset, adLockReadOnly While bookRS.EOF <> True Combo1.AddItem bookRS!access_no bookRS.MoveNext WendEnd Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)If KeyAscii = 13 Then Command7.Value = TrueEnd IfEnd Sub

86

Page 87: library documentation

Returning of books

This is a command button which is used to return the borrowed books by entering the accession no the title of the book is displayed in title box. Then enter borrower id in borrower’s information in borrower id box. Name of the person and status is displayed

In case of overdue the charge of the fine charge is displayed

By clicking save command button library transaction successfully saved.

87

Page 88: library documentation

Program code for returning of books

Dim xaccess_no, xborrower_id As String

Private Sub clear()

Combo1.Text = ""

Text1.Text = ""

Combo2.Text = ""

Text2.Text = ""

Text3.Text = ""

Text4.Text = Date

Text5.Text = Date

Label11.Caption = "0"

Label12.Caption = "0.00"

Label13.Caption = "0.00"

End Sub

Private Sub Combo1_Change()

Dim strPart As String, iLoop As Integer, iStart As Integer, strItem As String

If Not auto And Combo1.Text <> "" Then

iStart = Combo1.SelStart

strPart = Left$(Combo1.Text, iStart)

For iLoop = 0 To Combo1.ListCount - 1

strItem = UCase$(Combo1.List(iLoop))

If strItem Like UCase$(strPart & "*") And strItem <> UCase$(Combo1.Text) Then

auto = True

Combo1.SelText = Mid$(Combo1.List(iLoop), iStart + 1)

Combo1.SelStart = iStart

Combo1.SelLength = Len(Combo1.Text) - iStart

auto = False

Exit For

End If

Next iLoop

End If

If Combo1.Text = "" Then

Text1.Text = ""

Combo2.Text = ""

End If

88

Page 89: library documentation

If Combo1.Text <> "" And Text1.Text <> "" Then

Combo2.Enabled = True

Else

Combo2.Enabled = False

End If

End Sub

Private Sub Combo1_Click()

Set currentRS = New ADODB.Recordset

SQLstr = "Select * from current_borrow where access_no='" & Combo1.Text & "'"

currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly

If currentRS.EOF And currentRS.BOF Then

Exit Sub

End If

With currentRS

Text1.Text = !Title

Combo2.clear

xborrower_id = ""

While .EOF <> True

If !borrower_id = xborrower_id Then

.MoveNext

Else

Combo2.AddItem !borrower_id

xborrower_id = !borrower_id

.MoveNext

End If

Wend

Text2.Text = ""

Text3.Text = ""

Text4.Text = Date

Text5.Text = Date

End With

If Combo1.Text <> "" And Text1.Text <> "" Then

Combo2.Enabled = True

Else

Combo2.Enabled = False

End If

End Sub

Private Sub Combo1_KeyDown(KeyCode As Integer, Shift As Integer)

89

Page 90: library documentation

If KeyCode = vbKeyBack Or KeyCode = vbKeyDelete Then

auto = True

Combo1.SelText = ""

auto = False

ElseIf KeyCode = vbKeyReturn Then

Combo1_LostFocus

Combo1.SelStart = Len(Combo1.Text)

End If

End Sub

Private Sub Combo1_KeyPress(KeyAscii As Integer)

If KeyAscii = 13 Then

Set currentRS = New ADODB.Recordset

SQLstr = "Select * from current_borrow where access_no='" & Combo1.Text & "'"

currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly

If currentRS.EOF And currentRS.BOF Then

Exit Sub

End If

With currentRS

Text1.Text = !Title

Combo2.clear

xborrower_id = ""

While .EOF <> True

If !borrower_id = xborrower_id Then

.MoveNext

Else

Combo2.AddItem !borrower_id

xborrower_id = !borrower_id

.MoveNext

End If

Wend

Text2.Text = ""

Text3.Text = ""

Text4.Text = Date

Text5.Text = Date

End With

If Combo1.Text <> "" And Text1.Text <> "" Then

Combo2.Enabled = True

Else

Combo2.Enabled = False

90

Page 91: library documentation

End If

End If

End Sub

Private Sub Combo1_LostFocus()

Dim iLoop As Integer

If Combo1.Text <> "" Then

For iLoop = 0 To Combo1.ListCount - 1

If UCase$(Combo1.List(iLoop)) = UCase$(Combo1.Text) Then

auto = True

Combo1.Text = Combo1.List(iLoop)

auto = False

Exit For

End If

Next iLoop

End If

End Sub

Private Sub combo2_Change()

Dim strPart As String, iLoop As Integer, iStart As Integer, strItem As String

If Not auto And Combo2.Text <> "" Then

iStart = Combo2.SelStart

strPart = Left$(Combo2.Text, iStart)

For iLoop = 0 To Combo2.ListCount - 1

strItem = UCase$(Combo2.List(iLoop))

If strItem Like UCase$(strPart & "*") And strItem <> UCase$(Combo2.Text) Then

auto = True

Combo2.SelText = Mid$(Combo2.List(iLoop), iStart + 1)

Combo2.SelStart = iStart

Combo2.SelLength = Len(Combo2.Text) - iStart

auto = False

Exit For

End If

Next iLoop

End If

If Combo2.Text = "" Then

Text2.Text = ""

Text3.Text = ""

Text4.Text = Date

91

Page 92: library documentation

Text5.Text = Date

End If

End Sub

Private Sub Combo2_Click()

Set currentRS = New ADODB.Recordset

SQLstr = "select * from current_borrow where borrower_id='" & Combo2.Text & "'"

currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly

If currentRS.EOF And currentRS.BOF Then

Exit Sub

End If

With currentRS

Text2.Text = !Name

Text3.Text = !Status

Text4.Text = !borrow_date

On Error Resume Next

Text5.Text = !due_date

End With

End Sub

Private Sub combo2_KeyDown(KeyCode As Integer, Shift As Integer)

If KeyCode = vbKeyBack Or KeyCode = vbKeyDelete Then

auto = True

Combo2.SelText = ""

auto = False

ElseIf KeyCode = vbKeyReturn Then

combo2_LostFocus

Combo2.SelStart = Len(Combo2.Text)

End If

End Sub

Private Sub Combo2_KeyPress(KeyAscii As Integer)

If KeyAscii = 13 Then

Set currentRS = New ADODB.Recordset

SQLstr = "select * from current_borrow where borrower_id='" & Combo2.Text & "'"

currentRS.Open SQLstr, libCON, adOpenKeyset, adLockReadOnly

If currentRS.EOF And currentRS.BOF Then

Exit Sub

End If

With currentRS

Text2.Text = !Name

92

Page 93: library documentation

Text3.Text = !Status

Text4.Text = !borrow_date

On Error Resume Next

Text5.Text = !due_date

End With

End If

End Sub

Private Sub combo2_LostFocus()

Dim iLoop As Integer

If Combo2.Text <> "" Then

For iLoop = 0 To Combo2.ListCount - 1

If UCase$(Combo2.List(iLoop)) = UCase$(Combo2.Text) Then

auto = True

Combo2.Text = Combo2.List(iLoop)

auto = False

Exit For

End If

Next iLoop

End If

End Sub

Private Sub Command1_Click()

If currentRS.EOF And currentRS.BOF Then

MsgBox "There is no books currently borrowed!", vbExclamation

Exit Sub

End If

Combo1.Enabled = True

Combo1.SetFocus

Command1.Enabled = False

Command6.Caption = "&CANCEL"

End Sub

Private Sub Command2_Click()

Set bookRS = New ADODB.Recordset

SQLstr = "Select * from book_catalog where access_no='" & Combo1.Text & "'"

bookRS.Open SQLstr, libCON, adOpenKeyset, adLockOptimistic

With bookRS

!available_copy = !available_copy + 1

!borrow_copy = !borrow_copy - 1

.Update

93

Page 94: library documentation

.Close

End With

Set currentCMD = New ADODB.Command

SQLstr = "Delete * from current_borrow where access_no='" & Combo1.Text & "'" & " and borrower_id='" & Combo2.Text & "'"

With currentCMD

.ActiveConnection = libCON

.CommandType = adCmdText

.CommandText = SQLstr

.Execute

End With

clear

Combo1.Enabled = False

Command1.Enabled = True

Command2.Enabled = False

Command6.Caption = "CL&OSE"

MsgBox "Library Transaction Successfully Saved!", vbInformation

Set currentRS = New ADODB.Recordset

currentRS.Open "current_borrow", libCON, adOpenKeyset, adLockReadOnly

Combo1.clear

xaccess_no = ""

While currentRS.EOF <> True

If currentRS!access_no = xaccess_no Then

currentRS.MoveNext

Else

Combo1.AddItem currentRS!access_no

xaccess_no = currentRS!access_no

currentRS.MoveNext

End If

Wend

End Sub

Private Sub Command6_Click()

If Command6.Caption = "CL&OSE" Then

Unload Me

Else

clear

Combo1.Enabled = False

94

Page 95: library documentation

Combo2.Enabled = False

Command1.Enabled = True

Command2.Enabled = False

Command6.Caption = "CL&OSE"

End If

End Sub

Private Sub Form_Load()

dbconnect

clear

Combo1.Enabled = False

Combo2.Enabled = False

Command2.Enabled = False

Set currentRS = New ADODB.Recordset

currentRS.Open "current_borrow", libCON, adOpenKeyset, adLockReadOnly

xaccess_no = ""

While currentRS.EOF <> True

If currentRS!access_no = xaccess_no Then

currentRS.MoveNext

Else

Combo1.AddItem currentRS!access_no

xaccess_no = currentRS!access_no

currentRS.MoveNext

End If

Wend

End Sub

Private Sub Text2_Change()

If Text2.Text = "" Then

Command2.Enabled = False

Else

Command2.Enabled = True

End If

End Sub

Private Sub Text5_Change()

If Date > DateValue(Text5.Text) Then

Label11.Caption = Date - DateValue(Text5.Text)

Set feeRS = New ADODB.Recordset

95

Page 96: library documentation

feeRS.Open "charge", libCON, adOpenKeyset, adLockReadOnly

Label12.Caption = feeRS!charge_fee

Label13.Caption = Val(Label11.Caption) * Val(Label12.Caption)

Label12.Caption = Format(Label12.Caption, "###.00")

Label13.Caption = Format(Label13.Caption, "###.00")

Else

Label11.Caption = "0"

Label12.Caption = "0.00"

Label13.Caption = "0.00"

End If

End Sub

Reports section

Books masters list

Borrowers master list

96

Page 97: library documentation

Currently borrowed books list

Over due books list

Settings sectionSettings in library management systems

97

Page 98: library documentation

This is a command button which is used to add the book category in the list of books

This is a command button which is used to delete the book category in the list of books

Program coding for updating book category

Private Sub Command1_Click() frmaddcategory.Show vbModalEnd Sub

Private Sub Command2_Click() Set catCMD = New ADODB.Command SQLstr = "DELETE * FROM category where category ='" & List1.Text & "'" With catCMD .ActiveConnection = libCON .CommandType = adCmdText .CommandText = SQLstr .Execute End WithList1.clearlistrefresh

Command2.Enabled = FalseEnd Sub

Private Sub Command3_Click() Unload MeEnd Sub

Private Sub Form_Load() dbconnect listrefreshEnd Sub

Private Sub List1_Click()If List1.Text <> Empty Then Command2.Enabled = TrueEnd IfEnd Sub

Private Sub listrefresh()Set catRS = New ADODB.RecordsetcatRS.Open "category", libCON, adOpenKeyset, adLockReadOnlyWhile catRS.EOF <> True

98

Page 99: library documentation

List1.AddItem catRS!category catRS.MoveNextWendEnd Sub

User management

This is a command button which is used to add new user account by entering the username and password and by verifying it and save. User account is created.

Program coding for user management

Private Sub cmdAdd_Click() frmadduser.Show vbModalEnd Sub

Private Sub cmdCancel_Click() Unload MeEnd Sub

99

Page 100: library documentation

Private Sub cmdchange_Click()

'usersSet userRS = New ADODB.RecordsetSQLstr = "SELECT * FROM userlist where username='" & List1.Text & "'"userRS.Open SQLstr, libCON, adOpenKeyset, adLockOptimistic

frmchange.lblusername.Caption = userRS!UserName

frmchange.Show vbModal

End Sub

Private Sub cmdDelete_Click()

If List1.Text = "Administrator" Then MsgBox "Default User!", vbOKOnly + vbExclamation, "Warning..." List1.Text = "" cmdDelete.Enabled = False cmdchange.Enabled = False Exit SubEnd IfIf MsgBox("Delete Username and Password?", vbYesNo + vbQuestion, "DELETING USER") = vbNo Then List1.Text = "" cmdDelete.Enabled = False cmdchange.Enabled = False Exit SubEnd If 'users Set userCMD = New ADODB.Command SQLstr = "DELETE * FROM userlist where username ='" & List1.Text & "'" With userCMD .ActiveConnection = libCON .CommandType = adCmdText .CommandText = SQLstr .Execute End WithList1.clearCall listrefresh

cmdDelete.Enabled = Falsecmdchange.Enabled = False

MsgBox "Username and Password Deleted!", vbOKOnly + vbInformation, "Information"

End Sub

100

Page 101: library documentation

Private Sub Form_Load() dbconnect Call listrefreshEnd Sub

Private Sub listrefresh()'usersSet userRS = New ADODB.RecordsetuserRS.Open "userlist", libCON, adOpenKeyset, adLockReadOnly

While userRS.EOF <> True List1.AddItem userRS!UserName userRS.MoveNextWend

End Sub

Private Sub List1_Click()If List1.Text <> Empty Then cmdDelete.Enabled = True cmdchange.Enabled = TrueEnd IfEnd Sub

About

101

Page 102: library documentation

Program code for about

AM JAIN LIBRARY SYSTEMS

Option Explicit

' Reg Key Security Options...Const READ_CONTROL = &H20000Const KEY_QUERY_VALUE = &H1Const KEY_SET_VALUE = &H2Const KEY_CREATE_SUB_KEY = &H4Const KEY_ENUMERATE_SUB_KEYS = &H8Const KEY_NOTIFY = &H10Const KEY_CREATE_LINK = &H20Const KEY_ALL_ACCESS = KEY_QUERY_VALUE + KEY_SET_VALUE + _ KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + _ KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL ' Reg Key ROOT Types...Const HKEY_LOCAL_MACHINE = &H80000002Const ERROR_SUCCESS = 0Const REG_SZ = 1 ' Unicode nul terminated stringConst REG_DWORD = 4 ' 32-bit number

Const gREGKEYSYSINFOLOC = "SOFTWARE\Microsoft\Shared Tools Location"Const gREGVALSYSINFOLOC = "MSINFO"Const gREGKEYSYSINFO = "SOFTWARE\Microsoft\Shared Tools\MSINFO"Const gREGVALSYSINFO = "PATH"

Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, ByRef phkResult As Long) As LongPrivate Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, ByRef lpType As Long, ByVal lpData As String, ByRef lpcbData As Long) As LongPrivate Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Long) As Long

102

Page 103: library documentation

Private Sub cmdSysInfo_Click() Call StartSysInfoEnd Sub

Private Sub cmdOK_Click() Unload MeEnd Sub

Public Sub StartSysInfo() On Error GoTo SysInfoErr Dim rc As Long Dim SysInfoPath As String ' Try To Get System Info Program Path\Name From Registry... If GetKeyValue(HKEY_LOCAL_MACHINE, gREGKEYSYSINFO, gREGVALSYSINFO, SysInfoPath) Then ' Try To Get System Info Program Path Only From Registry... ElseIf GetKeyValue(HKEY_LOCAL_MACHINE, gREGKEYSYSINFOLOC, gREGVALSYSINFOLOC, SysInfoPath) Then ' Validate Existance Of Known 32 Bit File Version If (Dir(SysInfoPath & "\MSINFO32.EXE") <> "") Then SysInfoPath = SysInfoPath & "\MSINFO32.EXE" ' Error - File Can Not Be Found... Else GoTo SysInfoErr End If ' Error - Registry Entry Can Not Be Found... Else GoTo SysInfoErr End If Call Shell(SysInfoPath, vbNormalFocus) Exit SubSysInfoErr: MsgBox "System Information Is Unavailable At This Time", vbOKOnlyEnd Sub

Public Function GetKeyValue(KeyRoot As Long, KeyName As String, SubKeyRef As String, ByRef KeyVal As String) As Boolean Dim i As Long ' Loop Counter Dim rc As Long ' Return Code Dim hKey As Long ' Handle To An Open Registry Key Dim hDepth As Long ' Dim KeyValType As Long ' Data Type Of A Registry Key Dim tmpVal As String ' Tempory Storage For A Registry Key Value Dim KeyValSize As Long ' Size Of Registry Key Variable

103

Page 104: library documentation

'------------------------------------------------------------ ' Open RegKey Under KeyRoot {HKEY_LOCAL_MACHINE...} '------------------------------------------------------------ rc = RegOpenKeyEx(KeyRoot, KeyName, 0, KEY_ALL_ACCESS, hKey) ' Open Registry Key If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError ' Handle Error... tmpVal = String$(1024, 0) ' Allocate Variable Space KeyValSize = 1024 ' Mark Variable Size '------------------------------------------------------------ ' Retrieve Registry Key Value... '------------------------------------------------------------ rc = RegQueryValueEx(hKey, SubKeyRef, 0, _ KeyValType, tmpVal, KeyValSize) ' Get/Create Key Value If (rc <> ERROR_SUCCESS) Then GoTo GetKeyError ' Handle Errors If (Asc(Mid(tmpVal, KeyValSize, 1)) = 0) Then ' Win95 Adds Null Terminated String... tmpVal = Left(tmpVal, KeyValSize - 1) ' Null Found, Extract From String Else ' WinNT Does NOT Null Terminate String... tmpVal = Left(tmpVal, KeyValSize) ' Null Not Found, Extract String Only End If '------------------------------------------------------------ ' Determine Key Value Type For Conversion... '------------------------------------------------------------ Select Case KeyValType ' Search Data Types... Case REG_SZ ' String Registry Key Data Type KeyVal = tmpVal ' Copy String Value Case REG_DWORD ' Double Word Registry Key Data Type For i = Len(tmpVal) To 1 Step -1 ' Convert Each Bit KeyVal = KeyVal + Hex(Asc(Mid(tmpVal, i, 1))) ' Build Value Char. By Char. Next KeyVal = Format$("&h" + KeyVal) ' Convert Double Word To String End Select GetKeyValue = True ' Return Success rc = RegCloseKey(hKey) ' Close Registry Key Exit Function ' Exit GetKeyError: ' Cleanup After An Error Has Occured... KeyVal = "" ' Set Return Val To Empty String

104

Page 105: library documentation

GetKeyValue = False ' Return Failure rc = RegCloseKey(hKey) ' Close Registry KeyEnd Function

Private Sub lblDescription_Click()

End Sub

105

Page 106: library documentation

SUPPORTS Mastering Visual Basic 6.0 Visual Basic Programming Black Book MSDN Library Microsoft Windows Access 2003 Help

106