札记"/>
Delphi控件使用经验札记
1、notebook的使用
Pages属性里添加page
右键点击notebook, next page|Previous page,然后把控件加到页面上
2、设置toolbutton的快捷键
加个Action List
利用它来关联ToolButton
3、自定义组件注册过程
end;
procedure Register;implementationprocedure Register;
beginRegisterComponents('MYT', [TMYTHouse]);
end;
4、Delphi鼠标左键点击Button弹出快捷菜单Popupmenu
procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
PopupMenu2.Popup(Mouse.CursorPos.X-30,Mouse.CursorPos.Y+12);
end;
在光标所在位置弹出菜单;
procedure TForm1.Label1Click(Sender: TObject);
var
Point: TPoint;
begin
GetCursorPos(Point);
PopupMenu1.Popup(Point.X,Point.Y);
end;
[说明:两种方式实现的效果一样];
5、popupmenu.OwnerDraw默认为false,如果为true菜单可能会乱掉
6、包安装,包名相同会冲突,造成包安装不上,可能把包改名再安装
7、StringGrid根据条件设置单元格或行的颜色
procedure TfrmQuery.rzstrngrdDrawCell(Sender: TObject; ACol, ARow: Integer;Rect: TRect; State: TGridDrawState);
begin
// 改变行颜色if (rzstrngrd.Cells[11, ARow] = '异常') thenbeginif rzstrngrd.Canvas.Brush.Color <> clRed then // 设置背景颜色rzstrngrd.Canvas.Brush.Color := clRed;if rzstrngrd.Canvas.Font.Color <> clWhite then // 设置字体颜色rzstrngrd.Canvas.Font.Color := clWhite;endelsebeginif rzstrngrd.Canvas.Brush.Color <> clWindow then // 设置背景颜色rzstrngrd.Canvas.Brush.Color := clWindow;if rzstrngrd.Canvas.Font.Color <> clBlack then // 设置字体颜色rzstrngrd.Canvas.Font.Color := clBlack;end;rzstrngrd.Canvas.FillRect(Rect); //显示底色rzstrngrd.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, rzstrngrd.Cells[ACol, ARow]); //显示字// 改变单元格颜色//ACol 和 ARow 按需要进行设定!
// if (ACol = 11) and (ARow > 0) then
// begin
// if (rzstrngrd.Cells[11, ARow] = '异常') then
// begin
// if rzstrngrd.Canvas.Brush.Color <> clRed then
// rzstrngrd.Canvas.Brush.Color := clRed;
// end
// else
// begin
// if rzstrngrd.Canvas.Brush.Color <> clMoneyGreen then
// rzstrngrd.Canvas.Brush.Color := clMoneyGreen;
// end;
// rzstrngrd.Canvas.FillRect(Rect); //显示底色
// rzstrngrd.Canvas.TextOut(Rect.Left + 2, Rect.Top + 2, rzstrngrd.Cells[ACol, ARow]); //显示字
// end;
end;
8、DataSet定位查找记录
if qryTimePriceEUse.Locate('Weekname;TimeNum',VarArrayOf([1,1]),[]) then
9、Contnrs(Containers):存放容器类单元
10、做定时备份功能,如果时间设置到分钟,那么定时器间隔时间设置1分钟, 如果时间设置到秒钟,那么定时器间隔时间设置1秒钟,如果时间设置到小时,那么定时器间隔时间设置1小时,这样才能定时
10、delphi在线程中建立ado的数据库连接
如题,delphi在线程中建立ado的数据库连接 因为不在线程中使用ado连接不存在的数据库,则窗体会停止响应。比较麻烦,而我对线程方面又不太了解,所以希望有大侠帮我写下代码。谢谢!能详细点吗,最好给我做个demo 主窗体放三个edit,分别填服务器名称,sql用户名,密码 然后线程里是这样的代码 ConnMain:=TADOConnection.Create(nil); ConnMain.Connected:=False; connMain.ConnectionString:='Provider=SQLOLEDB.1;Password='+sqlpwd+';Persist Security Info=True;User ID='+sqluser+';Initial Catalog=''master'';Data Source='+server+''; ConnMain.Connected:=True;
procedure SendUDPThread.Execute();
var
AdoConn1:TADOConnection;
AdoQuery1:TAdoQuery;
begin
try
Lock.Enter;
AdoConn1:=TADOConnection.Create(nil);//动态创建ADO控件
AdoConn1.ConnectionString:=Form1.ADOConnection1.ConnectionString;
AdoConn1.LoginPrompt:=false;
AdoQuery1:=TAdoQuery.Create(Form1);
AdoQuery1.Connection:=AdoConn1; with AdoQuery1 do
begin
SQL.Add('select * from Users where id='+inttostr(RecordID)+' order by id desc'); //RecordID是我在线程创建时定义的一个私有变量
open;
While not eof do
begin
Form1.Memo1.Lines.Add(FieldByName('Name').AsString);
next;
end;
end; Form1.Memo1.Lines.Add('处理成功.');
Lock.Leave;
AdoConn1.Close;
AdoQuery1.Destroy;
AdoConn1.Destroy;//消除
except
Lock.Leave;
AdoConn1.Destroy;
AdoQuery1.Destroy;
Form1.Memo1.Lines.Add('处理失败.');
end;
11、frxReport frxDBSet设置UserName属性让报表设计器访问
frxReport.loadfromfile装载报表模板,showreport显示报表
12、TListview添加子项如果为空要添加空字符串,否则排序会报错
if FADOQuery.fieldbyname('TypeID').AsString = AMMETER_LIUYI thenbeginsubitems.Add(AMMETER_LIUYI_NAME);endelse if FADOQuery.fieldbyname('TypeID').AsString = AMMETER_DELIXI thenbeginsubitems.Add(AMMETER_DELIXI_NAME);endelsebeginsubitems.Add('');end;
12、多线程的基本规则之一是不得从非GUI线程与GUI进行交互。
13、SuperObject字段区别大小写,字段不存在会报错
14、SuperObejct应用知识
vJson,vItem: ISuperObject;iMtype: Integer;ArrJsonValue,ArrJsonKeyname :TSuperArray;ObjJsonKey :TSuperTableString;sRec := {"ac":200,"tag":{"reqid":"J80M7L"},"body":{"devices":[1,2,3,4,5,7,65534],"args":{"f01":1,"f02":2}}}vJson := nil;vJson := SO(sRec); vItem := vJson['body'];iMtype:= vJson['ac'].AsInteger;ObjJsonKey :=vJson['body'].AsObject;
ArrJsonKeyName:=ObjJsonKey.GetNames.AsArray; // 同一级对象名ArrJsonValue :=ObjJsonKey.GetValues.AsArray; // 同一级对象值iDeviceCount := vItem.A['devices'].Length; // 数组ObjJsonKey :=vItem['body']['args'].AsObject; // 对象里的对象// 数组也要判断
hdrItem := vItem['hdr'];if Assigned(hdrItem) thenbeginWriteOrderKeyname := hdrItem.A['writeOrder'];if Assigned(WriteOrderKeyname) thenbeginif WriteOrderKeyname.Length > 0 thenNeedOrder := True;end;end;// 增加对象
objectSuperSend.I['data.f01']:=StateToInt(tpDevice);{”data“:{"f01":1}}
15、Edit高度和字体要协调,要不高度会自动变化
16、TForm.autosize:= True窗口会拉不开
改为TForm.autosize:= False就可以了
17、状态栏显示时间可用RzClockStatus
18、mqtt登录事件触发不了,while循环要注意消息阻塞的问题,可以加上application.processmessage避免
procedure TfrmRemoteSetting.MQTTRecMsg(Sender: TObject; aTopic: UTF8String;aMessage: String; aQos: TMQTTQOSType; aRetained: Boolean);
varsRec: string;iMtype: Integer;vJson: ISuperObject;
beginsRec := aMessage;if Trim(sRec) = '' then Exit;tryvJson := nil;vJson := SO(sRec);if not Assigned(vJson) then Exit;tryiMtype := vJson['ac'].AsInteger;except
// self.ShowDebugMsg('Read Error Msg:' + sRec);Exit;end;case iMtype of113:beginFSettingResult := True;FReceived := True;end;end;exceptend;
end;procedure TfrmRemoteSetting.mqtqOffline(Sender: TObject;Graceful: Boolean);
beginSelf.FLoginSuccessed := False;
end;procedure TfrmRemoteSetting.mqtqOnline(Sender: TObject);
varsLoginState,sTop:string;
beginSelf.FLoginSuccessed := True;function TfrmRemoteSetting.SetGatewayCode(GatewayCode: string):Integer;
varRemoteDomainName,RemoteIP,sTempIp,sTop,strSend: string;RemotePort: Integer;LogTimeOut, RecTimeOut: Integer; // 等待响应超时时间mqttClient: TMQTTClient;sWill: string;
beginLogTimeOut := 100;RecTimeOut := 5;FReceived:=false;RemoteDomainName := Trim(edtDomain.Text);if(RemoteDomainName<>'')thenbeginsTempIp :=Trim(RemoteIP);//解析不到域名,则RemoteIP为主.if not HostToIP(RemoteDomainName,RemoteIP) then RemoteIP :=sTempIp;end;RemoteIP := Trim(RemoteIP);if not IsLegalIP(RemoteIP) then RemoteIP :='192.168.1.3';RemotePort := StrToInt(Trim(edtRomatePort.Text));mqttClient := TMQTTClient.Create(nil);trymqttClient.Broker := False;mqttClient.ClientID := RandomStr(20);mqttClient.Clean := True;mqttClient.Host := RemoteIP;mqttClient.Port := RemotePort;mqttClient.Username := Trim(edtAccount.Text);mqttClient.Password := Trim(des.DecryStrHex(edtPWD.Hint, '1reeBlLb'+DECODE_HALF_KEY));mqttClient.OnMsg := MQTTRecMsg;mqttClient.OnOnline := mqtqOnline;mqttClient.OnOffline := mqtqOffline;// sTop := PUBGETWAY + '/' + edtGatewayCode.hint;
// sWill := '{"ac":100,"body":{"status":0}}';
// mqttClient.SetWill(sTop, sWill, qtAT_LEAST_ONCE);if not mqttClient.Enabled thenmqttClient.Activate(True);while LogTimeOut <> 0 dobeginApplication.ProcessMessages;if FReceived then Break;if FLoginSuccessed thenbegin//订阅一个用来控制设备的主题sTop := SUBGETWAY + '/' + edtGatewayCode.hint;mqttClient.Subscribe(sTop, qtAT_LEAST_ONCE);Break;end;Sleep(1000);Dec(LogTimeOut);end;if not FLoginSuccessed thenbeginResult := 2; // 连接失败exit;end;sTop := PUBGETWAY + '/' + edtGatewayCode.Hint;strSend := '{"ac":113, "tag":{"reqid":"' + RandomStr(6) + '"},"hdr":{"SourceGWCode":"' + edtGatewayCode.Hint+'","NewGWCode" :"' + GatewayCode + '"}}';mqttClient.Publish(sTop, strSend, qtAT_LEAST_ONCE);while RecTimeOut <> 0 dobeginif FReceived then Break;Sleep(1000);Dec(RecTimeOut);end;if FSettingResult thenResult := 0else Result := 1;finallymqttClient.Free;end;
end;
19、DatasetProvider使用范例
procedure LoadRightTable(pUserName: string);
var qryUserTable, qryUserRight: TADOQuery;dpUserRight: TDataSetProvider;
begin//加载用户信息tryqryUserTable := TADOQuery.Create(nil);ExecADOQuery(qryUserTable, True, 'select * from UserTable where UserName=''' + pUserName + '''');if qryUserTable.RecordCount <= 0 thenisAdmin := Falseelsecase qryUserTable.FieldByName('UserType').AsInteger of0: isAdmin := false;1: isAdmin := True;end;finallyqryUserTable.Free;end;//加载用户权限信息tryqryUserRight := TADOQuery.Create(nil);dpUserRight := TDataSetProvider.Create(nil);ExecADOQuery(qryUserRight, True, 'select * from UserRight where UserName=''' + pUserName + '''');dpUserRight.DataSet := qryUserRight;qryUserRight.Open;if dsRightTable <> nil thenbegindsRightTable.Free;dsRightTable := nil;end;dsRightTable := TClientDataSet.Create(nil);dsRightTable.SetProvider(dpUserRight);dsRightTable.Open;finallyqryUserRight.Free;freeandnil(dpUserRight);//1234567890end;
end;
20、设置系统短日期的格式
// 设置WINDOWS系统的短日期的格式SetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, 'yyyy-MM-dd');Application.UpdateFormatSettings := False;// 设定程序本身所使用的日期时间格式LongDateFormat := 'yyyy-MM-dd';ShortDateFormat := 'yyyy-MM-dd';LongTimeFormat := 'hh:nn:ss';ShortTimeFormat := 'hh:nn:ss';DateSeparator := '-';TimeSeparator := ':';
21、InputQuery输入密码
procedure InputboxPassword(var MSG: TMessage); message InputBoxMessage;procedure TfrmMain.InputboxPassword(var MSG: TMessage);
varInputForm,Hedit: THandle;
beginInputForm:= Screen.Forms[0].Handle;if InputForm <> 0 thenbeginHedit:= FindWindowEx(InputForm,0,'Tedit',nil);SendMessage(Hedit,EM_SETPASSWORDCHAR,Ord('*'),0);end;
end;varstrResult: string;
beginPostMessage(Handle,InputboxMessage,0,0);if InputQuery('请输入维护密码', '密码:', strResult) thenbeginif strResult='dlxadmin123456' thenUAllocationDetail.showform()elseShowMessage('密码错误!');end;end;
22、MaskEdit 控件IP地址的Mask设置
(1) 添加 MaskEdit 控件。
(2) 选中TextEdit控件,查看控件属性。
(3) 展开Properties属性项,找到Mask属性项。
(4) 设置Mask属性项的EditMask属性值为:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
(5) 设置Mask属性项的MaskKind属性值为:emkRegExprEx
23、Toolbutton使Caption显示到图片右边
Toolbutton.List := True;
24、delphi 无窗体无界面exe怎么做?
要做一个无窗体的EXE,在Delphi下有两种方法:
console application
Hide all Foms(MainForm,esc.)
1、做一个控制台程序,生成console application工程文件的办法是:File\new\other\Console Application
2、隐藏窗体,跟无窗体差不多了吧,这样做最简单。
procedure TForm1.FormCreate(Sender: TObject);
begin
application.ShowMainForm:=false;
end;
25、combox实现键值对作用可用AddObject(objects[index]),Items.add(items[index])加values.add(values[index])
26、TListView如果caption列宽度为0,那么MultiSelect属性设为false,列表会显示不出来
27、mqtt频繁连接、断开原因
一、业务场景
我们在使用MQTT协议的时候,有些伙伴可能会遇到MQTT客户端频繁掉线、上线问题
二、原因分析及异常处理
原因:使用相同的clientID
方案:全局使用的clientID保证唯一性,可以采用UUID等方式
原因: 当前用户没有Topic权限
方案:如果配置有acl权限,则查询当前登录mqtt用户是否具有订阅对应topic的权限,无权时也会造成一直频繁断线重连
3. 原因:在回调函数内进行业务处理遇到异常并没有捕获
方案:在可能出现异常的语句块,进行try-catch捕获
/*** subscribe订阅后得到的消息会执行到这里*/@Overridepublic void messageArrived(String topic, MqttMessage message) {String msg = new String(message.getPayload());try {//此处可能因为收到的消息不合法,会造成JSON转化异常,若异常未捕获,会导致MQTT客户端掉线JSONObject jsonObject = JSON.parseObject(msg);String gwId = String.valueOf(jsonObject.get("gwId"));} catch (JSONException e) {log.error("JSON Format Parsing Exception : {}", msg);}}
28、datetimepick要设置下format,否则控件日期格式会受系统日期格式影响
29、fastreport4自动换行后还是出现显示不全的问题
解决办法:字符集改为:DEFAULT_CHARSET
30、DBGrid渲染背景颜色
procedure DBGridRowColor(Sender: TObject; //DBGrid颜色const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
beginif gdSelected in State thenbegin(Sender as TDBGrid).Canvas.Brush.Color := $000080FF; //当前选中单元格显示红色$00149BF0;//$005591B9;(Sender as TDBGrid).DefaultDrawColumnCell(Rect, DataCol, Column, State);endelsebegin//隔行改变网格背景色:if (Sender as TDBGrid).DataSource.DataSet.RecNo mod 2 = 0 then(Sender as TDBGrid).Canvas.Brush.Color := $00EFF1FC //定义背景颜色else(Sender as TDBGrid).Canvas.Brush.Color := $00B8E9FB; //$00F3EADE; // 定义背景颜色(Sender as TDBGrid).DefaultDrawColumnCell(Rect, DataCol, Column, State);end;
end;
31、嵌入窗体设置属性
FForm.WindowState :=wsMaximized;
FForm.Align :=alclient;
FForm.BorderStyle :=bsNone;
FForm.TransparentColor :=true;
32、ListBox第一行字体比其他行小
ListBox第一行字体比其他行小,把字体设置成“宋体”就可以了。
33、ClientDataSet概述
Delphi TClientDataSet控件的数据存储文件格式扩展名为Cds。它是一个基于文件数据存储和操作的控件。通过在Delphi中使用TClientDataSet控件,可以将应用程序与数据库驱动程序完全分离,并实现了传统数据集控件简单使用的特点,这为编写“精简”数据库应用程序提供了技术方法和手段。
更多推荐
Delphi控件使用经验札记
发布评论