從事軟件開發工做好多年了,學的越深刻越以爲本身無知,因此仍是要對知識保持敬畏之心,活到老,學到老!php
健身和代碼同樣都不能少,身體是革命的本錢,特別是咱們這種高危工種,因此小夥伴們運動起來!有沒有健身擼鐵,體脂如今是多少呀?明年(2020/03/22)徐州的馬拉松有沒有報名呀!?node
扯的有點遠了,接下來我將抽三天時間手把手教你基於Delphi7+Access,同時搭配第三方控件RC、AlphaControl(第三方控件主要用於美化界面),完成通用管理系統架構的設計。騷年,想一想是否是還有點小激動?程序員
這個是咱們系統實現部分的一個設計方案,由於系統是通用的嘛,因此這裏我就叫它Common Management System了,下面簡稱CMS。sql
這裏暫不作DFEMA和PFEMA的深層次分析,有BUG的系統纔是好系統,否則還要開發和維護人員作什麼?(客戶小姐姐:呸,渣男!)數據庫
騷年,扶好了,我要教你開車了,啊呸,我要教你開發了。緩存
建立一個Access文件,命名爲DataX.mdb,再建立兩張表,分別命名爲sysUser和sysUserAuthority,其中ID欄位自動生成,VDate欄位爲日期格式,其他欄位均爲長文本根式,並添加以下數據,以下圖。架構
Delphi ADOConnection動態鏈接Access數據庫 ide
啓動Delphi7,新建一個項目,分別命名爲:工程文件命名爲:CommonManagementSystem.dpr,單元文件命名爲:uMain.pas,主窗體命名爲:MainFrm。函數
而後保存,注意文件的保存位置,由於接下來鏈接Access數據庫時須要根據相對路徑來,參考下圖。工具
而後,在主窗體上放一個ADOConnection控件,命名爲conMain。接下來在工程onShow事件中寫以下代碼:
1 procedure TMainFrm.FormShow(Sender: TObject); 2 begin 3 // 動態鏈接Access數據庫 4 try 5 Screen.Cursor := crSQLWait; 6 ChDir(ExtractFilePath(Application.ExeName)); 7 ChDir('..'); 8 try //動態加載數據庫 9 conMain.Connected := False; 10 conMain.ConnectionString := 'Provider=Microsoft.Jet.OlEDB.4.0;Data Source=' + GetCurrentDir + '\DataX\DataX.mdb' + ';User ID=admin;Password=;Persist security Info=False'; 11 conMain.Connected := True; 12 conMain.LoginPrompt := False; 13 statusPaneAccess.Caption := '數據庫已鏈接';//狀態欄控件statusPane 14 Screen.Cursor := crDefault; 15 except 16 Screen.Cursor := crDefault; 17 statusPaneAccess.Caption := '數據庫未鏈接'; 18 MessageDlg('數據庫鏈接失敗,請確認!', mtError, [mbOK], 0); 19 end; 20 Screen.Cursor := crDefault; 21 except 22 statusPaneAccess.Caption := '數據庫未鏈接'; 23 MessageDlg('數據庫鏈接失敗,請確認!', mtError, [mbOK], 0); 24 end; 25 end;
OK,到這裏工程動態鏈接Access數據庫的功能已經實現了。
騷年,是否是感受很簡單,是的,你沒有看錯,跟着我一步步作,就是so easy!(🤫,不要忘記咱們的口號)其實複雜的功能都是經過簡單的功能組合起來的!因此,加油吧!騷年!
OK,回到主界面,在對象控制面板中選中MainFrm,單擊F11,在屬性控制面板中設定WindowState屬性設置爲wsMaximized,FormStyle屬性設置爲fsMDIForm,後續再創建的From,FormStyle屬性都設置爲fsMDIChild。
拖一個dxBarManager控件到主界面,命名爲dxbarManagerMain,雙擊該控件打開Toolbars界面,New兩個Toolbar分別爲菜單和快捷工具條,以下圖。
注意:這裏的菜單類型不能選錯!!!
注意:這裏的菜單類型不能選錯!!!
注意:這裏的菜單類型不能選錯!!!
OK,菜單設計好以後,咱們選中dxbarManagerMain控件,單擊F11,設置Style爲bmsFlat。而後雙擊打開控件,選中Toolbars中菜單,單擊F11,分別設置IsMainMenu、MultiLine和OneOnRow屬性爲True。以下圖。
OK,接下來,拖動菜單完成菜單架構設計,快捷工具條暫時不用,後續咱們再介紹,請看下圖。
鼠標點擊主界面空白處,單擊右鍵選擇 Add a Status Bar,添加一個statusBar控件,命名爲statusBarMain,而後選中statusBar,右鍵單擊New一些控件,分別設置其名稱、對齊方式、Caption等。
最終效果,以下:
OK,今天就到這裏了,明天,咱們繼續!騷年,注意關注、收藏、推薦,不要迷了路!!!
小夥伴我回來了,看到你們的評論,不由老淚縱橫,老兵不死,就是幹(⊙﹏⊙)。。。。。。。。。。。。。
OK,打起精神咱們接着昨天的內容繼續。
首先打開咱們的工程,新建一個Form,命名爲FrmLogin,而後開始進行前臺佈局,注意控件的命名必定要規範哈,我大概搞了一下登陸界面,以下圖。
而後,咱們新建一個單元文件,命名爲sysPublic.pas,用來聲明項目公用的函數、過程和變量,代碼以下(注意,這裏涉及到第三方控件:RC,cx)。
1 unit SysPublic; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Dialogs, Forms, 7 Classes, Variants, StdCtrls, Db, 8 Controls, WinSock, ShellApi, jpeg, graphics, TypInfo, 9 ExtCtrls, ComObj, ComCtrls, IdSMTP, IdMessage, 10 RzChkLst, ActnList, DBCtrls, RzTreeVw, RzGroupBar, DateUtils, 11 StrUtils, Math, RzPanel, cxStyles, RzDBCmbo, RzDBBnEd, 12 cxCustomData, cxGraphics, cxFilter, cxData, cxDataStorage, cxEdit, 13 cxDBData, cxTextEdit, cxGridCustomTableView, cxGridTableView, 14 cxGridDBTableView, Ora, MemDS, DBAccess, cxGridLevel, cxClasses, dxBar, 15 cxControls, cxGridCustomView, cxGrid, cxDropDownEdit, cxGridBandedTableView, cxGridDBBandedTableView, cxGridExportLink, Clipbrd, 16 IdBaseComponent, IdComponent, RzDBEdit, IdHash, IdHashMessageDigest, 17 IdFTP, IdFTPCommon, nb30, CwMboxLib_TLB, TlHelp32, winspool, Registry, 18 IdIPWatch, ADODB; 19 var 20 sysMsgBuffer, //消息緩存 21 sysWorkNO, //工號 22 sysUserName, //用戶名稱 23 sysGroupName, //登陸組 24 sysRealName, //用戶姓名 25 sysMac, //MAC地址 26 sysIP, //IP地址 27 sysDataXPath: string; //數據庫地址 28 function GetMd5Str(ContenStr: string): string; //獲取Md5碼 29 procedure OpenForm(FormClass: TFormClass; var fm; AOwner: TComponent); 30 procedure ExecSQL(sSQL: string); 31 procedure SetParam(V_Qry: TADOQuery; V_Param: string); 32 procedure Openquery(Q: TADOQuery; V_Sql: string); 33 procedure ComboAdd(Sender: Tstrings; SQLStr: string); 34 procedure ShowDxBarManagerMenu(); 35 36 function GetIPAddress(): Variant; 37 function SaveToExcel(GridMain: TcxGrid; FileName: string): string; 38 function GetSql(Ssql, V_Param: string): Variant; 39 function GetPosName(sName: string): string; 40 41 implementation 42 uses uMain; 43 44 procedure OpenForm(FormClass: TFormClass; var fm; AOwner: TComponent); 45 {根據傳遞過來的參數,打開相應的窗體} 46 var 47 i: integer; 48 Child: TForm; 49 begin 50 for i := 0 to Screen.FormCount - 1 do 51 if Screen.Forms[i].ClassType = FormClass then 52 begin 53 {檢查窗體是否已經打開,若是沒有打開,打開它, 54 若是已經打開,讓它正常顯示便可} 55 Child := Screen.Forms[i]; 56 if Child.WindowState = wsMinimized then 57 ShowWindow(Child.handle, SW_SHOWNORMAL) 58 else 59 ShowWindow(Child.handle, SW_SHOWNA); 60 if (not Child.Visible) then Child.Visible := True; 61 Child.BringToFront; 62 Child.Setfocus; 63 TForm(fm) := Child; 64 exit; 65 end; 66 Child := TForm(FormClass.NewInstance); 67 TForm(fm) := Child; 68 Child.Create(AOwner); 69 end; 70 71 procedure SetParam(V_Qry: TADOQuery; V_Param: string); 72 var 73 i: Integer; 74 S: tstringlist; 75 begin 76 s := tstringlist.Create; 77 s.Clear; 78 if v_Param <> '' then 79 begin 80 s.Text := stringreplace(v_Param, '[;]', '[KEY]', [rfReplaceAll]); 81 s.Text := stringreplace(s.Text, ';', #13 + #10, [rfReplaceAll]); 82 if S.Count > V_Qry.Fields.Count then 83 begin 84 ShowMessage('參數個數超過要求:' + V_Param + '[' + V_Qry.SQL.Text + ']'); 85 Abort; 86 end; 87 for i := 0 to s.Count - 1 do 88 begin 89 if (V_Qry.FieldDefList[i].Name = 'RQ1') or (V_Qry.FieldDefList[i].Name = 'RQ2') then 90 begin 91 V_Qry.FieldDefList[i].Name := s[i]; 92 end 93 else 94 begin 95 V_Qry.FieldDefList[i].Name := stringreplace(s[i], '[KEY]', ';', [rfReplaceAll]); 96 end; 97 end; 98 end; 99 end; 100 101 procedure OpenQuery(Q: TADOQuery; V_Sql: string); 102 begin 103 Q.Close; 104 Q.SQL.Text := V_Sql; 105 end; 106 107 procedure ComboAdd(Sender: Tstrings; SQLStr: string); 108 var 109 i, r: Integer; 110 begin 111 with MainFrm.qryTmp do 112 begin 113 Close; 114 SQL.Clear; 115 SQL.Add(SQLStr); 116 Open; 117 First; 118 R := RecordCount; 119 for i := 1 to r do 120 begin 121 Sender.Add(Fields[0].AsString); 122 Next; 123 end; 124 Close; 125 end; 126 end; 127 128 procedure ExecSQL(sSQL: string); 129 begin 130 MainFrm.qryTmp.Close; 131 MainFrm.qryTmp.SQL.Text := sSQL; 132 MainFrm.qryTmp.ExecSQL; 133 end; 134 135 function GetIPAddress(): Variant; 136 var 137 IPAddress: TIdIPWatch; 138 IPAdd_Buff: string; 139 begin 140 IPAddress := TIdIPWatch.Create(nil); 141 IPAdd_Buff := IPAddress.LocalIP; 142 if IPAdd_Buff <> '' then 143 begin 144 Result := IPAdd_Buff; 145 end 146 else 147 begin 148 Result := ''; 149 ShowMessage('獲取IP地址錯誤,請確認!'); 150 Abort; 151 end; 152 end; 153 154 function SaveToExcel(GridMain: TcxGrid; FileName: string): string; 155 var 156 SaveFileDialog: TSaveDialog; 157 begin 158 SaveFileDialog := TSaveDialog.Create(nil); 159 SaveFileDialog.FileName := FileName; 160 SaveFileDialog.Filter := '*.xls'; 161 if SaveFileDialog.Execute then 162 begin 163 if pos('.XLS', UpperCase(SaveFileDialog.FileName)) <= 0 then 164 SaveFileDialog.FileName := SaveFileDialog.FileName + '.XLS'; 165 ExportGridToExcel(SaveFileDialog.FileName, gridMain); 166 ShowMessage('數據已成功導出到您指定的目錄中'); 167 end; 168 Result := SaveFileDialog.FileName; 169 SaveFileDialog.Free; 170 end; 171 172 function GetSql(Ssql, V_Param: string): Variant; 173 var 174 S: Tstringlist; 175 I: Integer; 176 begin 177 S := Tstringlist.Create; 178 S.Clear; 179 OpenQuery(MainFrm.qryTmp, Ssql); 180 SetParam(MainFrm.qryTmp, V_Param); 181 MainFrm.qryTmp.Open; 182 if MainFrm.qryTmp.IsEmpty then 183 Result := '' 184 else 185 Result := MainFrm.qryTmp.Fields[0].Value; 186 if VarIsNull(result) then 187 begin 188 result := ''; 189 end; 190 MainFrm.qryTmp.Close; 191 MainFrm.qryTmp.Free; 192 end; 193 194 function GetPosName(sName: string): string; 195 var 196 s: string; 197 begin 198 s := Trim(sName); 199 if pos('(', s) > 0 then 200 s := copy(s, 0, pos('(', s) - 1); 201 Result := s; 202 end; 203 204 205 //獲取MD5碼 206 //ContenStr:原碼,返回MD5碼 207 208 function GetMd5Str(ContenStr: string): string; 209 var 210 RegMd5: TIdHashMessageDigest5; 211 RegDigest: T4x4LongWordRecord; 212 begin 213 RegMd5 := TIdHashMessageDigest5.Create; 214 RegDigest := RegMd5.HashValue(ContenStr); 215 Result := LowerCase(RegMd5.AsHex(RegDigest)); 216 end; 217 218 //刷線主界面菜單權限 219 220 procedure ShowDxBarManagerMenu(); 221 var 222 dxBar: TdxBarManager; 223 i, l, lIndex: integer; 224 sCap, sSql, m_menu_group, m_menu: string; 225 begin 226 with MainFrm.qryTmp do 227 begin 228 Close; 229 SQL.Clear; 230 SQL.Text := 'select a.GroupName, b.MenuName, a.UserName from sysUser a, sysUserAuthority b where a.GroupName = b.GroupName and a.UserName=:UserName and b.SystemName=:SystemName'; 231 Parameters.ParamByName('UserName').Value := sysUserName; 232 Parameters.ParamByName('SystemName').Value := 'CMS'; 233 234 Open; 235 dxBar := MainFrm.dxBarManagerMain; 236 for i := 1 to dxBar.Categories.Count - 2 do 237 begin 238 m_menu_group := dxBar.Categories.Strings[i]; 239 for l := 0 to dxBar.ItemCount - 1 do 240 begin 241 if dxBar.Items[l] is TdxBarButton then 242 begin 243 if dxBar.Items[l].Category = i then 244 begin 245 sCap := dxBar.Items[l].Caption; 246 lIndex := dxBar.Items[l].Index; 247 m_menu := sCap; 248 if Locate('MenuName', sCap, []) then 249 dxBar.Items[l].Enabled := true 250 else 251 dxBar.Items[l].Enabled := false; 252 end; 253 end; 254 end; 255 end; 256 end; 257 258 end; 259 260 end.
好,咱們在主窗體OnShow事件中(鏈接Access數據庫下面),寫以下代碼,功能是:主窗體Show以前,登陸窗體先彈出來。
1 // 系統登陸 2 if not assigned(FrmLogin) then 3 FrmLogin := TFrmLogin.create(Application); 4 FrmLogin.ShowModal;
而後,開始寫登陸事件,同時,更新主界面菜單權限和狀態欄信息。
1 begin 2 // 檢查錄入完整性 3 if (Trim(edtUserName.Text) = '') or (Trim(edtPassCode.Text) = '') then 4 begin 5 MessageDlg('用戶名或者密碼不能爲空,請確認!', mtWarning, [mbOK], 0); 6 edtUserName.SetFocus; 7 Abort; 8 end; 9 // 開始登陸 10 with qryLogin do 11 begin 12 Close; 13 SQL.Clear; 14 SQL.Text := 'select * from sysUser t where UserName=:UserName and PassCode =:PassCode'; 15 Parameters.ParamByName('UserName').Value := Trim(edtUserName.Text); 16 Parameters.ParamByName('PassCode').Value := GetMd5Str(Trim(edtPassCode.Text)); 17 Open; 18 if FindFirst then 19 begin 20 sysUserName := FieldByName('UserName').AsString; 21 sysGroupName := FieldByName('GroupName').AsString; ; 22 sysWorkNO := FieldByName('WorkNO').AsString; ; 23 sysRealName := FieldByName('RealName').AsString; 24 // 刷新菜單權限 25 ShowDxBarManagerMenu(); 26 // 更新狀態欄信息 27 MainFrm.statusPaneUser.Caption := '登陸用戶[' + sysUserName + '] 登錄組[' + sysGroupName + ']'; 28 FrmLogin.Tag := 1; 29 FrmLogin.Close; 30 end 31 else 32 begin 33 MessageDlg('用戶名或者密碼不正確,請確認!', mtWarning, [mbOK], 0); 34 edtUserName.SetFocus; 35 Abort; 36 end; 37 end; 38 39 end;
咱們這裏用FrmLogin.Tag做爲標記登陸成功與否的標記,默認狀況下設置爲0,密碼驗證經過時,tag賦值爲1,而後在FrmLogin的Close事件中判斷其是否爲1,不然直接終止程序。
1 procedure TFrmLogin.FormClose(Sender: TObject; var Action: TCloseAction); 2 begin 3 if FrmLogin.Tag <> 1 then 4 Application.Terminate; 5 end;
OK,看下如今的效果。
注意,我這裏手工在Access數據庫中增長了一個用戶admin,分組爲查詢組,其菜單權限相比於管理組,少了一個幫助的菜單。那小夥伴該問了,後續全部的權限都要在Access裏面改??固然不是了,下面咱們會繼續講解權限的管理。
MD5方式驗證和保存密碼
這裏相信你在上面登陸相關代碼中已經看到了,MD5轉換就是一個函數搞定的事。保存密碼也是同樣,直接調用MD5轉換函數進行轉化,而後再保存到數據庫便可。
//獲取MD5碼 //ContenStr:原碼,返回MD5碼 //須要引用 IdHash, IdHashMessageDigest單元 function GetMd5Str(ContenStr: string): string; var RegMd5: TIdHashMessageDigest5; RegDigest: T4x4LongWordRecord; begin RegMd5 := TIdHashMessageDigest5.Create; RegDigest := RegMd5.HashValue(ContenStr); Result := LowerCase(RegMd5.AsHex(RegDigest)); end;
首先,根據實際狀況,通常除主窗體以外的全部窗體的FormStyle屬性都要設置成fsMDIChild,而後在Project-Options中將子窗體移到右邊。以下圖。
另外,分別在子窗體的Create、Close和Destroy寫以下事件(注意主界面窗體列表菜單的名稱爲dxBarListWindows):
1 procedure TFrmMDIChildTest.FormClose(Sender: TObject; 2 var Action: TCloseAction); 3 begin 4 //窗口關閉時,從內存中移除窗口 5 Action := caFree; 6 FrmMDIChildTest := nil; 7 end; 8 9 procedure TFrmMDIChildTest.FormCreate(Sender: TObject); 10 begin 11 //窗口建立時,在窗口菜單中加入窗口的菜單 12 MainFrm.dxBarListWindows.Items.AddObject(Caption, Self); 13 end; 14 15 procedure TFrmMDIChildTest.FormDestroy(Sender: TObject); 16 begin 17 //窗口關閉時,在窗口菜單中移除窗口的菜單 18 with MainFrm.dxBarListWindows.Items do 19 Delete(IndexOfObject(Self)); 20 end;
主界面窗口列表菜單下(name:dxBarListWindows),須要再增長以下事件用來激活窗體列表:
1 procedure TMainFrm.dxBarListWindowsClick(Sender: TObject); 2 begin 3 with dxBarListWindows do 4 TCustomForm(Items.Objects[ItemIndex]).Show; 5 end; 6 7 procedure TMainFrm.dxBarListWindowsGetData(Sender: TObject); 8 begin 9 with dxBarListWindows do 10 ItemIndex := Items.IndexOfObject(ActiveMDIChild); 11 end;
好的,咱們再看下效果,能夠完成窗體列表中相關菜單的添加、激活和銷燬:
RzCheckTree方式設計常見用戶權限
這裏主要用到checkTree和數據的增刪改查。
源碼以下:
1 unit uUserSet; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, sCalculator, cxStyles, cxCustomData, cxGraphics, cxFilter, 8 cxData, cxDataStorage, cxEdit, DB, cxDBData, cxTextEdit, cxDropDownEdit, 9 ADODB, Ora, ComCtrls, RzTreeVw, StdCtrls, RzCmboBx, RzLabel, cxGridLevel, 10 cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxClasses, 11 cxControls, cxGridCustomView, cxGrid, Mask, RzEdit, RzRadChk, RzButton, 12 ExtCtrls, RzPanel, RzTabs, cxCalendar, cxCheckBox, dxBar; 13 14 type 15 TFrmUserSet = class(TForm) 16 pageControlMain: TRzPageControl; 17 tabSheetUserSet: TRzTabSheet; 18 groupBoxParams: TRzGroupBox; 19 btnRefresh: TRzBitBtn; 20 btnAdd: TRzBitBtn; 21 btnSave: TRzBitBtn; 22 btnDelete: TRzBitBtn; 23 checkBoxUserName: TRzCheckBox; 24 edtUserName: TRzEdit; 25 btnDodify: TRzBitBtn; 26 cxGridMain: TcxGrid; 27 cxGridMainDBTableView1: TcxGridDBTableView; 28 cxGridMainLevel1: TcxGridLevel; 29 tabSheetAuthSet: TRzTabSheet; 30 groupBoxParamsA: TRzGroupBox; 31 labGroupName: TRzLabel; 32 lblNewGroupName: TRzLabel; 33 cbbGroupName: TRzComboBox; 34 btnSaveA: TRzBitBtn; 35 btnDeleteA: TRzBitBtn; 36 edtNewGroupName: TRzEdit; 37 btnAddA: TRzBitBtn; 38 checkTreeMain: TRzCheckTree; 39 qryTmp: TADOQuery; 40 qryUser: TADOQuery; 41 dsUser: TDataSource; 42 qryUserAuthority: TADOQuery; 43 cxGridMainDBTableView1Column1: TcxGridDBColumn; 44 cxGridMainDBTableView1Column2: TcxGridDBColumn; 45 cxGridMainDBTableView1Column3: TcxGridDBColumn; 46 cxGridMainDBTableView1Column4: TcxGridDBColumn; 47 cxGridMainDBTableView1Column5: TcxGridDBColumn; 48 cxGridMainDBTableView1Column6: TcxGridDBColumn; 49 cxGridMainDBTableView1Column7: TcxGridDBColumn; 50 procedure btnRefreshClick(Sender: TObject); 51 procedure FormClose(Sender: TObject; var Action: TCloseAction); 52 procedure FormDestroy(Sender: TObject); 53 procedure FormCreate(Sender: TObject); 54 procedure btnAddClick(Sender: TObject); 55 procedure btnSaveClick(Sender: TObject); 56 procedure btnDeleteClick(Sender: TObject); 57 procedure btnDodifyClick(Sender: TObject); 58 procedure LoadMenu(dxBar: TdxBarManager); 59 procedure cbbGroupNameClick(Sender: TObject); 60 procedure btnSaveAClick(Sender: TObject); 61 procedure btnDeleteAClick(Sender: TObject); 62 procedure btnAddAClick(Sender: TObject); 63 procedure qryUserBeforePost(DataSet: TDataSet); 64 private 65 { Private declarations } 66 public 67 { Public declarations } 68 end; 69 70 var 71 FrmUserSet: TFrmUserSet; 72 73 implementation 74 uses 75 uMain, sysPublic; 76 {$R *.dfm} 77 78 procedure TFrmUserSet.LoadMenu(dxBar: TdxBarManager); 79 var 80 I, L: integer; 81 Tnode: TTreenode; 82 begin 83 with checkTreeMain.Items do 84 begin 85 Clear; 86 for i := 0 to dxBar.Categories.Count - 1 do 87 begin 88 Tnode := AddChild(nil, GetPosName(dxBar.Categories.Strings[i])); 89 for l := 0 to dxBar.ItemCount - 1 do 90 if dxBar.Items[l] is TdxBarButton then 91 if dxBar.Items[l].Category = i then 92 begin 93 AddChild(Tnode, GetPosName(dxBar.Items[l].Caption)); 94 end; 95 end; 96 end; 97 with qryTmp do 98 begin 99 Close; 100 SQL.Text := 'select MenuName from sysUserAuthority where SystemName=''CMS'' and GroupName=:GroupName'; 101 Parameters.ParamByName('GroupName').Value := cbbGroupName.Text; 102 Open; 103 for i := 0 to checkTreeMain.Items.Count - 1 do 104 if checkTreeMain.Items[i].Level > 0 then 105 if Locate('MenuName', checkTreeMain.Items[i].Text, []) then 106 checkTreeMain.ItemState[i] := csChecked; 107 Close; 108 end; 109 end; 110 111 procedure TFrmUserSet.btnRefreshClick(Sender: TObject); 112 begin 113 if not checkBoxUserName.Checked then 114 begin 115 with qryUser do 116 begin 117 Close; 118 SQL.Clear; 119 SQL.Text := 'select * from sysUser t'; 120 Open; 121 end; 122 end 123 else 124 begin 125 with qryUser do 126 begin 127 Close; 128 SQL.Clear; 129 SQL.Text := 'select * from sysUser t where t.UserName =''' + edtUserName.text + ''' or t.WorkNO =''' + edtUserName.text + ''''; 130 Open; 131 end; 132 end; 133 btnDodify.Enabled := True; 134 end; 135 136 procedure TFrmUserSet.FormClose(Sender: TObject; var Action: TCloseAction); 137 begin 138 //窗口關閉時,從內存中移除窗口 139 Action := caFree; 140 FrmUserSet := nil; 141 end; 142 143 procedure TFrmUserSet.FormDestroy(Sender: TObject); 144 begin 145 //窗口關閉時,在窗口菜單中移除窗口的菜單 146 with MainFrm.dxBarListWindows.Items do 147 Delete(IndexOfObject(Self)); 148 end; 149 150 procedure TFrmUserSet.FormCreate(Sender: TObject); 151 begin 152 //窗口建立時,在窗口菜單中加入窗口的菜單 153 MainFrm.dxBarListWindows.Items.AddObject(Caption, Self); 154 cbbGroupName.Items.Clear; 155 ComboAdd(cbbGroupName.Items, 'select distinct GroupName from sysUserAuthority where SystemName=''CMS'' order by GroupName'); 156 TcxComboBoxProperties(cxGridMainDBTableView1Column4.Properties).Items.Text := cbbGroupName.Items.Text; 157 cbbGroupName.ItemIndex := 0; 158 cbbGroupName.OnClick(Self); 159 end; 160 161 procedure TFrmUserSet.btnAddClick(Sender: TObject); 162 begin 163 qryUser.Append; 164 btnSave.Enabled := True; 165 end; 166 167 procedure TFrmUserSet.btnSaveClick(Sender: TObject); 168 begin 169 qryUser.Post; 170 btnSave.Enabled := False; 171 MessageDlg('保存成功,請不要重複操做!', mtInformation, [mbOK], 0); 172 end; 173 174 procedure TFrmUserSet.btnDeleteClick(Sender: TObject); 175 begin 176 case MessageDlg('刪除將沒法恢復,您確認要繼續刪除嗎?', mtWarning, [mbYes, 177 mbNo], 0) of 178 mrYes: 179 begin 180 qryUser.Delete; 181 btnSave.Enabled := False; 182 MessageDlg('刪除成功,請不要重複操做!', mtInformation, [mbOK], 0); 183 end; 184 mrNo: 185 begin 186 Exit; 187 end; 188 end; 189 end; 190 191 procedure TFrmUserSet.btnDodifyClick(Sender: TObject); 192 begin 193 btnSave.Enabled := True; 194 btnDelete.Enabled := True; 195 qryUser.Edit; 196 end; 197 198 procedure TFrmUserSet.cbbGroupNameClick(Sender: TObject); 199 begin 200 LoadMenu(MainFrm.dxBarManagerMain); 201 end; 202 203 procedure TFrmUserSet.btnSaveAClick(Sender: TObject); 204 var 205 I: Integer; 206 begin 207 for i := 0 to checkTreeMain.Items.Count - 1 do 208 begin 209 if checkTreeMain.Items[i].Level > 0 then 210 if checkTreeMain.ItemState[i] = csChecked then 211 begin 212 with qryTmp do 213 begin 214 Close; 215 SQL.Clear; 216 SQL.Text := 'SELECT * FROM sysUserAuthority WHERE GROUPNAME =:GROUPNAME AND MENUNAME =:MENUNAME'; 217 Parameters.ParamByName('GROUPNAME').Value := cbbGroupName.Text; 218 Parameters.ParamByName('MENUNAME').Value := checkTreeMain.Items.Item[i].Text; 219 Open; 220 if RecordCount = 0 then 221 begin 222 qryUserAuthority.Close; 223 qryUserAuthority.SQL.Clear; 224 qryUserAuthority.SQL.Text := 'INSERT INTO sysUserAuthority(GROUPNAME, MENUNAME, SystemName) VALUES(:GROUPNAME, :MENUNAME, :SystemName)'; 225 qryUserAuthority.Parameters.ParamByName('GROUPNAME').Value := cbbGroupName.Text; 226 qryUserAuthority.Parameters.ParamByName('MENUNAME').Value := checkTreeMain.Items.Item[i].Text; 227 qryUserAuthority.Parameters.ParamByName('SystemName').Value := 'CMS'; 228 qryUserAuthority.ExecSQL; 229 end; 230 end; 231 end 232 else 233 begin 234 ExecSql('DELETE FROM sysUserAuthority WHERE SystemName= ''CMS'' AND GROUPNAME=''' + cbbGroupName.Text + ''' AND MENUNAME=''' + checkTreeMain.Items.Item[i].Text + ''''); 235 end; 236 end; 237 TcxComboBoxProperties(cxGridMainDBTableView1Column4.Properties).Items.Text := cbbGroupName.Items.Text; 238 ShowMessage('保存成功!'); 239 end; 240 241 procedure TFrmUserSet.btnDeleteAClick(Sender: TObject); 242 begin 243 if MessageDLG('您肯定要刪除該分組權限嗎?', mtconfirmation, [MBOK, MBCANCEL], 0) = MRCANCEL then exit; 244 ExecSql('Delete from sysUserAuthority where SystemName=''' + Application.Title + ''' AND groupname=''' + cbbGroupName.Text + ''''); 245 end; 246 247 procedure TFrmUserSet.btnAddAClick(Sender: TObject); 248 begin 249 if edtNewGroupName.Text = '' then 250 begin 251 ShowMessage('請先輸入組名!'); 252 exit; 253 end; 254 cbbGroupName.Items.Add(edtNewGroupName.Text); 255 cbbGroupName.ItemIndex := cbbGroupName.Items.Count - 1; 256 cbbGroupName.OnClick(self); 257 ShowMessage('添加成功!'); 258 edtNewGroupName.Text := ''; 259 end; 260 261 procedure TFrmUserSet.qryUserBeforePost(DataSet: TDataSet); 262 begin 263 if (Pos(' ', qryUser.FieldByName('UserName').AsString) > 0) or (Pos(' ', qryUser.FieldByName('PassCode').AsString) > 0) then 264 begin 265 ShowMessage('用戶名或密碼中不能有空格!請從新輸入'); 266 Abort; 267 end; 268 if (qryUser.State = dsInsert) or ((qryUser.State = dsEdit) and (Length(qryUser.FieldByName('PassCode').AsString) < 20)) then 269 begin 270 qryUser.FieldByName('PassCode').AsString := GetMd5Str(qryUser.FieldByName('PassCode').AsString); 271 end; 272 end; 273 274 end.
OK,今天就到這裏吧,其實整個通用的管理系統架構基本已經完成了,咱們明天主要完善/美化一下界面。
感受寫博客比作技術還累,專業的事情交給專業的人作(⊙﹏⊙)。。。。。。
能看到這裏的絕逼是Delphi真愛。。。。。
小夥伴,今天咱們繼續打卡。
imageList圖標倉庫,主要用於菜單的美化。
在主界面拖一個imageList控件,命名爲imageListMain,而後添加一些圖標進去。以下圖。
而後,完成dxBarManagerMain和imageListMain的綁定(dxBarManagerMain的image屬性)。
OK,至此,就能夠爲主菜單增長圖標了(選中菜單,根據須要選擇imageIndex)。
後來我想了一下,關於第三方庫,就再也不講解了,你們有興趣能夠自行研究。說句傲嬌的話,作技術最重要的是功能,花裏胡哨的幹啥呀!
不過話說回來,好的UI界面可以極大的提升用戶體驗(啪啪打臉(⊙﹏⊙)),下面帶你們看下AlphaControl皮膚控件的Demo效果(到這裏下載控件包AlphaControl官網)。
最後,做爲一名程序員,語言只是一種工具,如何快速、高效的達到項目需求,纔是最主要的。
最最重要的是:咱們要時刻保持對技術的熱愛,興趣是最好的老師,活到老學到老!
OK,最後看下咱們這個項目的整體效果!
任何疑問、建議、意見請留言或者私信我哦~~~~
點擊下載源碼,有任何疑問歡迎和我交流。
做者:Jeremy.Wu
出處:https://www.cnblogs.com/jeremywucnblog/ 本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。