1、CB静态编译设置
2、CB10.3设置经典编译器(用于解决10.3弹出代码提示慢)
3、C++Builder生成Release版本 :
project->Options->C++Compiler->Build Configuration 选择 Release
project->Options->C++Linker中取消Use dynamic RTL前的对钩
在project->Options->Packages中取消Builder with runtime packages的对钩
project-Configuration Manager->Configuration 选择 Release
由於中間上方箭頭朝右的按鈕時灰色的
所以鼠標點擊一下左邊列表的行;然後中間上方的灰色的箭頭朝右的箭頭變成綠色,
這時候可以點擊了,點擊綠色按鈕,再重新編譯即可;
工程目錄下產生了Release目錄
C++Builder6的方法:
在project->Options->Compiler中点击Release,
在project->Options->Packages中取消Builder with runtime packages的对钩
在project->Options->Linker中取消Use dynamic RTL前的对钩
4、类视图
5、C++Builder安装APP获得USB使用权限通知的方法和注意事项
1、在AndroidManifest.template.xml处添加,
,在里添加Intent过滤,
2、*****关键点,也是奇怪的地方*****,一定要建空工程,Blank Application模板,否则选其它模板会偶尔才能得到通知。
6、用c++ builder调用cef4,编写一个简单浏览器源代码
#pragma hdrstop
#pragma argsused
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "libcef.lib")
#pragma comment(lib, "libcef_dll_wrapper.lib")
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
// 存储指向CefApp的指针
CefRefPtr g_app;
// 存储指向CefBrowser的指针
CefRefPtr g_browser;
// 存储指向CefBrowserHost的指针
CefRefPtr g_host;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// 用于创建CefApp的回调函数
CefRefPtr CreateCefApp()
{
return g_app;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
// 初始化cef
CefMainArgs args(NULL);
CefSettings settings;
CefRefPtr app(new CefApp);
g_app = app;
CefInitialize(args, settings, app.get(), NULL);
// 创建cef浏览器
CefWindowInfo info;
CefBrowserSettings browser_settings;
CefRect rect;
rect.x = rect.y = 0;
rect.width = Form1->ClientWidth;
rect.height = Form1->ClientHeight;
info.SetAsChild(Form1->Handle, rect);
CefBrowserHost::CreateBrowser(info, new CefClientHandler, "http://www.baidu.com", browser_settings, NULL);
}
//---------------------------------------------------------------------------
// CefClient的实现
class CefClientHandler : public CefClient, public CefLifeSpanHandler, public CefRenderHandler, public CefLoadHandler
{
public:
CefClientHandler(){}
~CefClientHandler(){}
// CefClient
public:
virtual CefRefPtr GetLifeSpanHandler() { return this; }
virtual CefRefPtr GetRenderHandler() { return this; }
virtual CefRefPtr GetLoadHandler() { return this; }
// CefLifeSpanHandler
public:
virtual void OnAfterCreated(CefRefPtr browser)
{
g_browser = browser;
g_host = browser->GetHost();
}
// CefRenderHandler
public:
virtual bool GetViewRect(CefRefPtr browser, CefRect &rect)
{
rect.x = rect.y = 0;
rect.width = Form1->ClientWidth;
rect.height = Form1->ClientHeight;
return true;
}
virtual void OnPaint(CefRefPtr browser, PaintElementType type, const RectList &dirtyRects, const void *buffer)
{
TMemoryStream *pStream = new TMemoryStream();
pStream->WriteBuffer(buffer, Form1->ClientWidth * Form1->ClientHeight * 4);
Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
pBitmap->PixelFormat = pf32bit;
pBitmap->Width = Form1->ClientWidth;
pBitmap->Height = Form1->ClientHeight;
pBitmap->LoadFromStream(pStream);
delete pStream;
Form1->Canvas->Draw(0, 0, pBitmap);
delete pBitmap;
}
// CefLoadHandler
public:
virtual void OnLoadEnd(CefRefPtr browser, CefRefPtr frame, int httpStatusCode)
{
g_host->SendFocusEvent(true);
}
private:
IMPLEMENT_REFCOUNTING(CefClientHandler);
};
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
g_browser->GetHost()->CloseBrowser(true);
// 清理cef
CefShutdown();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
if (g_host.get())
{
g_host->WasResized();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (g_host.get())
{
CefKeyEvent event;
event.windows_key_code = Key;
g_host->SendKeyEvent(event);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
if (g_host.get())
{
CefMouseEvent event;
event.x = X;
event.y = Y;
g_host->SendMouseMoveEvent(event, false);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (g_host.get())
{
CefMouseEvent event;
event.x = X;
event.y = Y;
g_host->SendMouseClickEvent(event, MBT_LEFT, false, 1);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (g_host.get())
{
CefMouseEvent event;
event.x = X;
event.y = Y;
g_host->SendMouseClickEvent(event, MBT_LEFT, true, 1);
}
}
//---------------------------------------------------------------------------
7、常用插件地址
PDF Library (Winsoft) 1.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/pdflibrary-20200831.zip
PDF Library for Android (Winsoft) 1.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/apdflibrary-20200831.zip
Portable (Winsoft) 1.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/portable-20200831.zip
Printing Library for Android (Winsoft) 2.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/aprinting-20200831.zip
SVG Canvas (Winsoft) 1.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/svgcanvas-20200831.zip
SVG Canvas for FireMonkey (Winsoft) 1.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fsvgcanvas-20200831.zip
TypeLib Import (Winsoft) 1.0
http://altd.embarcadero.com/getit/public/libraries/WinSoft/tlimport-20200831.zip
USB library for Android (Winsoft) 1.7
http://altd.embarcadero.com/getit/public/libraries/WinSoft/ausblib-20200831.zip
Utils library (Winsoft) 1.6
http://altd.embarcadero.com/getit/public/libraries/WinSoft/utils-20200831.zip
XML library (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/xml-20200831.zip
Zip for Android (Winsoft) 1.9
http://altd.embarcadero.com/getit/public/libraries/WinSoft/azip-20200831.zip
TwineCompile 5.2.1
http://altd.embarcadero.com/getit/public/libraries/TwineCompile/TwineCompile-20200903.zip
InstantObjects 2.8
http://altd.embarcadero.com/getit/public/libraries/InstantObjects/InstantObjects-20200904.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200908.zip
Camera for iOS (Winsoft) 1.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/icamera-20200904.zip
Camera for macOS (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/xcamera-20200904.zip
ComPort for Android (Winsoft) 2.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/acomport-20200904.zip
Audio Component Suite (Winsoft) 2.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/AudioComponentSuite-20200903.zip
Audio Component Suite for FireMonkey (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/faudiocs-20200903.zip
Barcode component (Winsoft) 5.1
http://altd.embarcadero.com/getit/public/libraries/WinSoft/barcode-20200903.zip
Barcode for FireMonkey (Winsoft) 5.6
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fbarcode-20200903.zip
Burn CD/DVD/Blu-ray Component Suite (Winsoft) 4.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/burncs-20200903.zip
Burn CD/DVD/Blu-ray Component Suite for FireMonkey (Winsoft) 1.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fburncs-20200903.zip
Camera (Winsoft) 2.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/wcamera-20200903.zip
ComPort for macOS (Winsoft) 2.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/xcomport-20200904.zip
Controller (Winsoft) 1.1
http://altd.embarcadero.com/getit/public/libraries/WinSoft/controller-20200904.zip
DAO Database Collection (Winsoft) 5.8
http://altd.embarcadero.com/getit/public/libraries/WinSoft/daods-20200904.zip
DirectX Joystick (Winsoft) 4.0
http://altd.embarcadero.com/getit/public/libraries/WinSoft/dxjoystick-20200904.zip
FMXLinux 1.47
http://altd.embarcadero.com/getit/public/libraries/FMXLinux/fmxlinux-20200909.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200909.zip
FMXLinux 1.48
http://altd.embarcadero.com/getit/public/libraries/FMXLinux/fmxlinux-202009102.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200910.zip
FMXLinux 1.47
http://altd.embarcadero.com/getit/public/libraries/FMXLinux/fmxlinux-20200909.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200909.zip
FMXLinux 1.48
http://altd.embarcadero.com/getit/public/libraries/FMXLinux/fmxlinux-202009102.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200910.zip
DirectX Joystick for FireMonkey (Winsoft) 1.6
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fdxjoystick-20200908.zip
Image Acquisition Component Suite (Winsoft) 1.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/wiacs-20200908.zip
Image Acquisition Component Suite for FireMonkey (Winsoft) 1.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fiacs-20200908.zip
PNGComponents 1.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/PNGComponents-20200911.zip
Image Acquisition for macOS (Winsoft) 1.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/xia-20200908.zip
IOPort component (Winsoft) 5.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/ioport-20200908.zip
Joystick component (Winsoft) 4.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/joystick-20200908.zip
Joystick for FireMonkey (Winsoft) 1.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fjoystick-20200908.zip
Media Recorder for Android (Winsoft) 1.8
http://altd.embarcadero.com/getit/public/libraries/WinSoft/amediarec-20200908.zip
OBR component (Winsoft) 4.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/obr-20200908.zip
OBR for FireMonkey (Winsoft) 3.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fobr-20200908.zip
OCR component (Winsoft) 8.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/ocr-20200908.zip
OCR for FireMonkey (Winsoft) 5.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/focr-20200908.zip
PDFium Component Suite (Winsoft) 5.8
http://altd.embarcadero.com/getit/public/libraries/WinSoft/pdfium-20200908.zip
PDFium Component Suite for FireMonkey (Winsoft) 5.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fpdfium-20200908.zip
SimpleMAPI Component Suite (Winsoft) 3.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/smapi-20200908.zip
VCL Windows Style - Lucky Point. Updated for HighDPI.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-LuckyPoint-20200915.zip
VCL Windows Style - Puerto Rico. Updated for HighDPI.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-PuertoRico-20200915.zip
VCL Windows Style - Stellar. Includes 2 variants: light and dark editors. Updated for HighDPI.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-Stellar-20200915.zip
VCL Windows Style - Wedgewood Light. Updated for HighDPI.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-WedgewoodLight-20200915.zip
VCL Windows Style - Zircon. Includes 2 variants: with different colors of selection and some other elements. Updated for HighDPI.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-Zircon-20200915.zip
Orpheus for VCL 4.4 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/Orpheus-20200915.zip
WinInet Component Suite (Winsoft) 4.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/wininet-20200914.zip
WinInet Component Suite for FireMonkey (Winsoft) 1.5
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fwininet-20200914.zip
WinRT (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/winrt-20200914.zip
WinRT for FireMonkey (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fwinrt-20200914.zip
Communication Protocol Suite (Winsoft) 4.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/protsuite-20200917.zip
SynEdit for VCL 1.5 (update)
http://altd.embarcadero.com/getit/public/libraries/TurboPack/SynEdit-20200921.zip
Communication Protocol Suite for FireMonkey (Winsoft) 1.8
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fprotsuite-20200917.zip
ComPort component (Winsoft) 6.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/comport-20200917.zip
ComPort for FireMonkey (Winsoft) 2.1
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fcomport-20200917.zip
ComPort for Linux (Winsoft) 1.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/lcomport-20200917.zip
JavaBridge (Winsoft) 2.6
http://altd.embarcadero.com/getit/public/libraries/WinSoft/jbridge-20200917.zip
SVGIconImageList VCL && FMX 2.0.1 (update)
http://altd.embarcadero.com/getit/public/libraries/SVGIconImageList/SVGIconImageList-202009213.zip
Bluetooth Library for Android (Winsoft) 1.6
http://altd.embarcadero.com/getit/public/libraries/WinSoft/abtlib-20200917.zip
OBR Library (Winsoft) 2.4
http://altd.embarcadero.com/getit/public/libraries/WinSoft/obrlib-20200827.zip
OBR Library for Android (Winsoft) 5.2
http://altd.embarcadero.com/getit/public/libraries/WinSoft/aobrlib-20200827.zip
Office Component Suite (Winsoft) 3.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/office-20200917.zip
Video Stream (Winsoft) 1.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/vstream-20200917.zip
WebView (Winsoft) 1.8
http://altd.embarcadero.com/getit/public/libraries/WinSoft/webview-20200917.zip
WebView for FireMonkey (Winsoft) 1.9
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fwebview-20200917.zip
Camera for FireMonkey (Winsoft) 2.3
http://altd.embarcadero.com/getit/public/libraries/WinSoft/fcamera-20200903.zip
NetCom7 7.2.0.570
https://github.com/DelphiBuilder
RAD Server Installer for Linux 1.0 (update)
http://altd.embarcadero.com/getit/public/libraries/RADServer/RADServerInstallerLinux-20200924.zip
Bookmarks 1.6.2
http://altd.embarcadero.com/getit/public/libraries/ParnasusPlugins/ParnassusBookmarks_XSydney-20200910.zip
VCL Windows Style - Material Oxford Blue
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-MaterialOxfordBlue-20200915.zip
VCL Windows Style - Material Patterns Blue.
http://altd.embarcadero.com/getit/public/libraries/DelphiStyles/VCLStyle-MaterialPattensBlue-20200915.zip
IconFontsImageList VCL && FMX 2.2.1
http://altd.embarcadero.com/getit/public/libraries/IconFontsImageList/IconFontsImageList-20200921.zip
8、绘制ITEM
void BubbleListPrivate::drawItems(QPainter *painter)
{
// 绘制item区域
painter->save();
qreal nItemY = 0;
int nWidth = this->width();
nWidth = (0 == nWidth % 2) ? nWidth : nWidth + 1;
// 起始位置抬高
nItemY = ITEM_SPACE + ITEM_TITLE_HEIGHT; //20+20
//遍历items
for (int nIndex = m_currIndex; nIndex < m_items.count(); nIndex++)
{
//解析消息内容
QString strMsg = m_items.at(nIndex)->GetText();
quint8 msgType = m_items.at(nIndex)->GetMsgType();
quint8 nOrientation = m_items.at(nIndex)->GetOrientation();
QString strPixmap = m_items.at(nIndex)->GetStrPixmap();
//气泡长宽
qreal bubbleWidth = 0;
qreal bubbleHeight = 0;
// 计算右边的宽度x
int nX = 0;
int nY = 0;
QPixmap pixmap;
QPainterPath path;
// 气泡和内容的矩形框
QRectF msgRect;
QRectF bobbleRect;
// --------------------计算气泡和文字的绘制范围 ----------------------------//
switch (msgType) {
case Text:
{
//根据文字设置气泡长宽
QFontMetrics fm(m_font);
bubbleWidth = fm.width(strMsg);
bubbleHeight = fm.height();
//遍历查找换行符,换行符影响气泡高度
QStringList strMsgList = strMsg.split("\n");
qreal nLineWidth = 0;
qreal nLineHeight = 0;
// 换行符会影响计算宽度和高度
for (int i = 0; i < strMsgList.size(); i++) {
if (nLineWidth < fm.width(strMsgList.at(i)))
{
nLineWidth = fm.width(strMsgList.at(i));
nLineWidth = nLineWidth < (nWidth * 2 / 3) ? nLineWidth: (nWidth * 2 / 3);
}
nLineHeight = nLineWidth < (nWidth * 2 / 3) ? fm.height() * 1.5 : (((nLineWidth / ((nWidth * 2 / 3))) + 1) * ITEM_HEIGHT / 3);
bubbleHeight += nLineHeight;
}
bubbleWidth = nLineWidth;
// 文字初始化高度 聊天框y轴坐标
nY = this->height() - nItemY - bubbleHeight;
}
break;
case Audio:
break;
default:
break;
}
// --------------------绘制气泡和文字 ----------------------------//
if (Right == nOrientation) { //气泡在右
painter->save();
painter->setPen(QPen(QColor("#D3D3D3"), 1));
// 绘制头像边框
painter->drawRoundedRect(nWidth - 55, nY, 50, 50, 2, 2);
// 绘制头像
QPixmap pixmap(strPixmap);
if (!pixmap.isNull()) {
painter->drawPixmap(nWidth - 55 + 1, nY + 1, 48, 48, pixmap);
}
painter->restore();
// 绘制名字和当前时间
painter->save();
// 计算文字的宽度
QFont font("微软雅黑", 8);
QFontMetrics fm(font);
QString strTitle = m_items.at(nIndex)->GetDatetime() + " ";
strTitle += m_items.at(nIndex)->GetName();
painter->setPen(QColor("#666666"));
painter->setFont(font);
painter->drawText(nWidth - 55 - fm.width(strTitle) - 10, nY + fm.height() / 2, strTitle);
painter->restore();
// 根据文字计算气泡的顶点位置
nX = (nWidth) - 95 - bubbleWidth;
if (nX < 0) {
nX = -bubbleWidth - 95 + nWidth ;
}
// 计算气泡框
nY += ITEM_TITLE_HEIGHT;
//构建矩形框 左上角顶点坐标x,y , 长度 ,高度
bobbleRect = QRectF(nX, nY, bubbleWidth + 20, bubbleHeight);
msgRect = QRectF(nX + 10, nY, bubbleWidth, bubbleHeight);
qDebug() << "bubbleWidth:" << bubbleWidth;
qDebug() << "nX:" << nX;
painter->save();
//气泡框圆角
path.addRoundedRect(bobbleRect, 10, 10);
// 计算气泡右边的三角
//设置三角形的三个顶点的x,y轴
path.moveTo(nWidth - 75, nY + 15);
path.lineTo(nWidth - 65, nY + 20);
path.lineTo(nWidth - 75, nY + 25);
painter->setPen(Qt::red);
painter->fillPath(path, QColor("#FFFFFF"));
painter->restore();
}else { //气泡在左
// 绘制头像
painter->save();
painter->setPen(QColor("#D3D3D3"));
// 绘制边框
painter->drawRoundedRect(5, nY, 50, 50, 2, 2);
// 绘制头像
QPixmap pixmap(strPixmap);
if (!pixmap.isNull()) {
painter->drawPixmap(6, nY + 1, 48, 48, pixmap);
}
painter->restore();
nX = 75;
// 绘制名字和当前时间
painter->save();
// 计算文字的宽度
QFont font("微软雅黑", 8);
QFontMetrics fm(font);
QString strTitle = m_items.at(nIndex)->GetName() + " ";
strTitle += m_items.at(nIndex)->GetDatetime();
painter->setPen(QColor("#666666"));
painter->setFont(font);
painter->drawText(nX, nY + fm.height() / 2, strTitle);
painter->restore();
// 绘制气泡区域
painter->save();
nY += ITEM_TITLE_HEIGHT;
bobbleRect = QRectF(nX, nY, bubbleWidth + 20, bubbleHeight);
// 绘制文字区域
msgRect = QRectF(nX + 10, nY, bubbleWidth, bubbleHeight);
// 左边三角
path.addRoundedRect(bobbleRect, 5, 5);
path.moveTo(nX, nY + 15);
path.lineTo(nX - 10, nY + 20);
path.lineTo(nX, nY + 25);
// 背景色
painter->fillPath(path, QColor("#9EE656"));
painter->restore();
}
//-------------绘制文字---------------
painter->setPen(QColor("#000000"));
painter->setFont(m_font);
if(Text == msgType){
painter->drawText(msgRect, strMsg, Qt::AlignVCenter | Qt::AlignLeft);
}
//绘制后续消息
nItemY += (bobbleRect.height()) + ITEM_SPACE + ITEM_TITLE_HEIGHT;
}
painter->restore();
}
9、关于 调用 JNI JAR 的说明和注意事项,调用第三方 JAR SDK 和 翻译 安卓 JAVA 代码
对于安卓系统
谷歌 API 提供的是 JNI 接口。
第三方 JAR SDK 提供的也是 JNI 接口。
您的手机,一般会内置 安卓 SDK 的大部分接口。
但是有些 API 可能没有内置。
FMX 安卓工程默认会给您提供多个 谷歌的 SDK 。
因此 大部分 谷歌的 JAR,您都不需要自己去找。
对于 第三方的 SDK 来说。
基本上分为 jar + so、纯jar 和 纯so 三种。
纯so 就是类似于 dll 的接口。只需要注意 dll 是 stdcall 类型,其他所有平台都是 cdecl 类型。 不写是不行的。因为 delphi 不写的是默认的 pascall 类型。
如果你不会调用 dll 那么也就不会调用 so 。
本文不讨论调用 so。
但是告诉你们 SO 文件文件的路径:编辑 RemotePath 列。路径是(xe5) library\lib\armeabi (xe6或以上) library\lib\armeabi-v7a
以上路径的 so 一般是给 jar 加载用的。
自己加载可以用 LoadLibaray 或者 dlopen 。记得用对应的 FreeLibaray 和 dlclose
也可以像定义 DLL 一样,定义 so 的函数接口。这样就不用写代码加载了。
如果只有你自己用,也可以发布到其他你能访问的路径。但是,只能写代码加载了,路径要写完整。
对于 jar 无论它有没有提供 so 。我们都只能使用 jar 的对外接口。
除非是安卓基本 API,或者是 DELPHI 已经提供的 JAR 。否则 其他的 JAR ,只要你用到了,就必须加入到 安卓的 工程中。 具体如何添加,请自行百度。
即便是 基本 API,EMBT 也没有全部给大家 转成 JNI 接口。
所以当你用到一个 EMBT 没翻译的 API 的时候,请自行用 工具 翻译。
翻译:可以理解为 语言的转换,接口的导出,也就是变成 pascal语法的 pas 文件
当你得到一个 JAR 的时候,请用工具翻译成 pascal 文件。
目前推荐 2 个 工具。
1. 官方的 java2op.exe 。支持 .jar .java .class 三种格式的文件。
2. 爱吃猪头肉的 JarOrClass2pas 。支持 .jar .class 两种格式的文件。
其他工具都是垃圾。千万别用。否则活该。
当你用工具得到 pas 文件后,注意:
1. 一般会得到 大量的 无用的,错乱的,重复的 接口。请将它们删除。
2. 即便是没问题的接口,如果用不到,也请删除。
3. 转换工具会写出一些 uses 的单元,这些单元可能不存在。
对于jar 或 class 文件引用了别的 jar,就容易出现不认识的 unit 的 uses。请找到这些 jar 继续翻译。
当你 jar 已经加入到 安卓项目中。
jni pas 文件已经准备好,也加入到 安卓项目中。
就可以开始调用 jar 接口了。
接下来说明下基本的类型变化。
Int 就是 Integer ,很多基本对象大家都可以自己想到。
string 是 JString 。
Uri 要翻译成 Jnet_Uri。
上述两个类型 EMBT 提供了互相转换的函数。
还有个别的其他改变名称的类型。这里就无法一一列举了。如果 你发现一些 类名 EMBT 应该提供了,但是找不到,请通过 Signatur 在 Find in Files 对话框中查找。
例如 搜索 java/lang/Class 可以发现 JCalss 也改名了。
int [] 就是 TJavaArray
但是 string [] 是 TJavaObjectArray
ArrayList
而且任何 ArrayList
有些类型的名称比较特别。例如 java 的 Phone 类型 EMBT 已经翻译成了 JCommonDataKinds_Phone。这是因为 Phone 是 CommonDataKinds 的内部类。
数据类型 OK 了。那么就谈谈 Java 类的 构造函数 类成员 类方法 和 普通成员 普通方法。
如果不懂这些,请自行百度。建议好好看看 面向对象开发 课程。
Java 类一般会提供默认构造函数,到了 pas 里头,他的函数名叫 init 小写。默认不带参数。
但是很多 java 类 会重载 构造函数,提供带参数的版本。
接下来,我们需要百度下你打算使用的 jni 的 demo 。
安卓开发,最大的优势就是,网上全是 demo ,虽然是 java 语言的。
找到 demo 代码之后,你就需要 按照 代码的逻辑,进行语言的翻译。
下面提供几种常见的 代码 翻译。
1. 某对象的 构造。
1.1 java 代码
xxx x = new xxx(参数或没有参数);
1.2 翻译代码
var
x: Jxxx;
begin
x := TJxxx.JavaClass.init(参数或没有参数);
if x = nil then 出错了。
end;
上述代码,演示了构造函数的使用。 注意:
1.3 x 是 Jxxx
1.4 TJxxx.JavaClass 是 TJ 开头的。JavaClass. 能提供给你 这个类的所有类方法,类成员,包括构造函数。
1.5 不是所有类都可以使用默认构造函数的。
1.6 如果你确认可以使用默认构造函数,但是 pas 中没有。可以使用如下代码构造。
x := TJxxx.Create;
2. 某对象的 非默认构造,使用类方法的构造。
2.1 java 代码 通过 new 创建对象。
xxx x = new xxx.yyy(参数或没有参数);
2.2 java 代码 不通过 New 创建对象。
xxx x = xxx.yyy(参数或没有参数);
2.3 翻译代码
var
x: Jxxx;
begin
x := TJxxx.JavaClass.yyy(参数或没有参数);
if x = nil then 出错了。
end;
上述代码,演示了使用类方法来得到类 xxx 的对象。
3. 通过其他类的对象,来得到对象 x。
3.1 java 代码
xxx x = yyy.zzz(参数或没有参数);
3.2 翻译代码
var
x: Jxxx;
begin
x := yyy.zzz(参数或没有参数);
if x = nil then 出错了。
end;
非常简单,就是加了个冒号。yyy 是另一个对象。 zzz 可以是 yyy 对象的类方法、类成员、普通方法或普通成员。
4. 通过强制类型转换,来得到对象 x,一般不常用。
4.1 java 代码
xxx x = (xxx)yyy.zzz(参数或没有参数);
zzz 返回的类型不是 xxx,也不是 xxx 的派生类。
4.2 翻译代码
var
xLocalObject: JObject;
x: Jxxx;
begin
xLocalObject := yyy.zzz(参数或没有参数);
或者
xLocalObject := JObject(yyy.zzz(参数或没有参数));
if xLocalObject = nil then 出错了。
x := TJxxx.Wrap((xLocalObject as ILocalObject).GetObjectID);
if x = nil then 出错了。
end;
注意 Wrap 的开头,也是 TJ
经过 [臺北]wildsky(2590003092) 的验证
x := TJxxx.Wrap((yyy.zzz(参数或没有参数) as ILocalObject).GetObjectID);
这样少一个变量的写法。部分机器发生闪退。
用两个变量来完成,就不会发生闪退。
对于某些 JNI 服务
经过 [深圳]机器猫(5909386) 的验证
TJContext.JavaClass.VIBRATOR_SERVICE
TJActivity.JavaClass.VIBRATOR_SERVICE
用上面个可以,下面的就会闪退。
出现的错误提示可能是:Project xxx.apk raised exception class Aborted(6).
J 开头 TJ 开头 都是 约定俗成。你也可以 SB 开头 TSB 开头。
默认 TJ 开头的是 DELPHI 的类型。
J 开头的才是 JAVA 的类型。
TJxxx.JavaClass 返回 JxxxClass 类型,这个类型专门代表类方法和类属性。 Jxxx 则代表类对象的类型。
5. 不通过变量来操作某类型 xxx 的代码。
5.1 java 代码
xxx.yyy(参数或没有参数).zzz(参数或没有参数);
5.2 翻译代码
TJxxx.JavaClass.yyy(参数或没有参数).zzz(参数或没有参数);
5.3 xxx 是类型 yyy 是类函数。
5.4 可以出现 xxx.JavaClass.yyy(参数或没有参数).zzz(参数或没有参数).nnn(参数或没有参数); 这种多级的调用。
6. 已存在对象 xxx 调用他的方法来操作的代码。
6.1 java 代码
xxx.yyy(参数或没有参数);
6.2 翻译代码
xxx.yyy(参数或没有参数);
6.3 xxx 是对象 yyy 是该对象的类函数或成员函数。
6.4 可以出现 xxx.yyy(参数或没有参数).zzz(参数或没有参数); 这种多级的调用。
7. 使用常量
7.1 java 中的常量,一般都是类的成员。而且一般是类的类成员。
7.2 java 代码
xxx = yyy.zzz;
//xxx 是一个变量 yyy 是一个类名 zzz 是常量名
7.3 翻译代码
xxx := TJyyy.JavaClass.zzz;
7.4 也就是说 zzz 被翻译到了 Jyyy 的 Class 版本的 接口中。
7.4 效果等于
xxx := JyyyClass.zzz;
7.5 不建议用上面的代码。请按 7.3 的版本写。
注意,对于我们 pascal 来说没有参数括号是可以省略的。 C JAVA 等是不允许省略的。
对于 数组 TJavaArray
可以写
var
xxx: TJavaArray
begin
xxx := TJavaArray
然后用 xxx.Items[编号] 来访问。
end;
TJavaObjectArray 也是如上的办法。
目前没有发现动态修改数量的办法。也就是数组的个数,是建立的时候就确定的。
8. 一些常用的 Jni 和 pascal 类型的互转
打开
unit Androidapi.Helpers;
自己去看吧。
有 TBytes string JCharSequence JURI JLong 等几种常用类型的互转。
如果你使用一个方法,发生Segmentation fault(11) 可能是对象为 nil 或者 函数不存在(一般是版本不同,有的版本函数就不存在)。
如果你使用一个方法,发生非法操作,说明没有这个方法(大概是名称或参数有错误)。
如果提示你 java class xxx could not be found,如果是官方 xxx ,那么是你的手机内部没提供这个接口,你可以自己找官方的 jar 文件来加入、
如果是第三方的 xxx,那更简单了,这个 xxx 对应的 jar 文件,你肯定没加入到 你的工程中。
如果你确认你加了(参考 [img]http://www.2pascal.com/data/attachment/forum/201505/14/175004tw0xaoi23h2xwkeh.jpg[/img] 第二个箭头,确认加了,就删了再加一遍,还不行,可能是你编译出的结果目录,存在垃圾,删除编译结果目录试试。),建议做如下操作
打开你的 Android 工程,点菜单项 Project—>Deployment,打开部署子窗口,点 Revert to Default 按钮,就是那个向左的弯箭头:
出现 Revert to default 对话框:
选中第一项“Revert for all configurationsthe active platform”,点 OK。
注意:不论其默认选项如何,在这里都必须选择其中一个并点OK,否则你的Android程序在调用JAR文件时将会出现“Java Class xxx could not befound”的错误。
以上文字来源于 [url=http://blog.sina.com.cn/s/blog_648d306d0102vfgq.html]http://blog.sina.com.cn/s/blog_648d306d0102vfgq.html[/url]
如果 Objs 是 TJavaObjectArray
TJxxxx.Warp(Objs.GetRawItem(x)) 试试。多谢 [深圳]机器猫(5909386) 的测试。
一般建议
uses
{$IF CompilerVersion >= 27.0} // >= XE6
Androidapi.Helpers,
{$ENDIF}
FMX.Helpers.Android,
Androidapi.JNI.JavaTypes,
Androidapi.NativeActivity;
当需要一个 Activity 对象的时候,我们只能提供 TAndroidHelper.Activity。因为 FMX 只存在这个一个 Activity。。java UI 代码中 self(this) 就是 Activity 对象
当需要一个 View 对象的时候,默认的是 TAndroidHelper.Activity.getWindow.getDecorView。其他的就不知道了。
当需要一个 Context 对象的时候,可以试试 TAndroidHelper.Context,这是全局的。
当你需要一个 getApplicationContext 对象的时候,可以试试 TAndroidHelper.Context.getApplicationContext,这是因为你不懂自己看源码,不是我的错。
{$IF CompilerVersion >= 30.0} // >=RAD10
TAndroidHelper.Activity
TAndroidHelper.Context
{$ELSE}
SharedActivity
SharedActivityContext
{$ENDIF}
无论如何,当你得到一个 java 对象一定要先检查 是不是 nil,否则轻则提示错误,重则闪退。
EMBT 经常忘了检查,所以就闪退,例如你在窗体中放了一个 IAP 支付控件,很多手机上都会闪退,就是因为没检查 nil。
如果是正在开发的 APP 在任何机器上闪退,特别是旧版本升级来的,别人复制给你的。一般是 发布信息混乱,造成的。工程的 发布(部署)信息需要【重新加载】。Deployment 需要 Revert to Default
如果是任何APP。包括新建的空 APP,在特定的机器上一运行就闪退。说明是一个 BUG。请在本群的 不看后悔 系列中 解压 找 XE 修复 APK 启动,提示 Cannot deploy," " file not found.txt。
当你使用一个 jni 对象的时候。如果是个可以显示的对象。很多时候需要:
CallInUiThread(
procedure
begin
jni 代码。
end);
有时候 还得换成 CallInUIThreadAndWaitFinishing。
只有这样 代码才不会死锁。
也就是 如果不这么写。你的 APP 就会出现 未响应。
有些不是显示的 jni 对象,也需要这样写。不过不常见。
如果你收到一个错误 CalledFromWrongThreadException,就是需要 CallInUiThread 了。
如果收到的是
Can't create handler inside thread that has not called Looper.prepare()
也是需要 CallInUiThread 了。多谢 [新会]supermay(15832782) 测试。
注意:不要将大片代码进入上述的代码块中。尽量减少相关代码。最好是用 DEBUG ,找出弹出这类错误提示的代码行。不会 DEBUG 请看书。
在 安卓的世界里,回调函数是不存在的。但是可以使用接口来做到回调。
一般这种接口 会被定义成 Listener。
当你需要继承(实现)一个 java 接口的时候,就需要查看有关代码了。
使用 DELPHI IDE,在 Search 菜单打开 Find In Files 对话框。
输入搜索关键字
= class(TJavaLocal,
搜索范围 Search in directories
选择到你的安装目录的源代码目录,选中 Indude subdirectories
好好找吧。
你会找到好多代码。
他们都是继承(实现) java 接口的好例子。
按照面向对象的说法 接口必须实现。所以上面找到的代码是必然的。
然后定义出这个类的 对象,就可以当参数在 jni 中使用了。
不过这种类型,是 delphi 的实现,所以别忘了 free。
个人建议大家好好研读【unit System.Android.Bluetooth;】。
有时候 接口提供的 回调函数 可能是在线程中运行的。
这时候你实现这个函数的时候,要注意。
UI 对象 无论是 FMX 的还是 jni 的。你都需要线程同步。
线程同步的简单方法就是。
...
//线程或回调函数里的一些代码。
TThread.Synchronize(nil, //或者 用线程自己的同步函数。 Synchronize(
procedure
begin
//你的界面交互代码。
end);
//继续线程或回调函数的代码。
...
如果是调用事件,
建议用
TThread.Queue(nil,
procedure
begin
//你的事件调用。
end);
如果你 DEBUG 中收到了 Bitmap size too big 的提示,有可能就是 该用同步,没同步造成的。
10.2 以后,不会再有这个提示。 Bitmap 支持线程中使用了。
10.2 开始,主线程和 UI 线程 为同一个线程了。
CallInUiThread 应该可以大批量的不用了。
有了以上知识,你基本上翻译 java 的代码,就不成问题了。
别说,你不会 顺序、判断、循环、函数调用。
如果你想了解一个 第三方 view 是如何显示到 FMX 中的。
可以参考 unit FMX.WebBrowser.Android 和 unit FMX.Media.Android。
另外,很多操作,都需要对应的权限,别忘了加上。
对于 4.4 以上的系统,想要访问外置存储卡。需要加上
这 2 个权限。
目前 IDE 没有提供。
您需要在 AndroidManifest.template.xml 文档中,自己加入,用 IDE 就能打开,找到 <%uses-permission%>,将上述权限文字加入到 这行下面就行。
但是,不保证所有机器都有效。
如果发现需要使用 安卓下面的 命令行,例如执行 su sh ping 等。
可以参考 QDac http://blog.qdac.cc 的代码,可能叫 QRuntime。
也可以参考 本群的 重启你的手机 源代码。
对于学习 翻译 安卓 java 代码为 pascal 。
最好先看 EMBT 的源代码。然后看 EMBT 的 Samples。
也可以好好看 本群的群共享。
里头好多调用 jni 的 DEMO。
10、RAD编译的exe,要跑在XP上,要改这2个设置
11、【特别处理】修改 hosts 文件及防火墙规则禁止BDS.exe等联网
1)添加以下信息到 hosts 文件中 (C:\Windows\System32\drivers\etc):
127.0.0.1 license.embarcadero.com
127.0.0.1 track.embarcadero.com
127.0.0.1 comapi.embarcadero.com
127.0.0.1 object.ws.sanctx.embarcadero.com
127.0.0.1 external.ws.sanctx.embarcadero.com
127.0.0.1 services.server.v8.srs.sanctuary.codegear.com
127.0.0.1 LicenseUsageServicesImpl.services.server.v8.srs.sanctuary.codegear.com
127.0.0.1 RegistrationServicesImpl.services.server.v8.srs.sanctuary.codegear.com
127.0.0.1 LicenseRenewalServicesImpl.services.server.v8.srs.sanctuary.codegear.com
127.0.0.1 license-stage.codegear.com
127.0.0.1 license.codegear.com
127.0.0.1 installers.embarcadero.com
2)以管理员模式打开命令行窗口,运行以下命令对 bds.exe、LicenceManager.exe 文件禁止联网规则:
Netsh.exe advfirewall firewall add rule name="RADStudio" program="C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\bds.exe" protocol=any dir=out enable=yes action=block profile=Private,Public,Domain
Netsh.exe advfirewall firewall add rule name="RADStudio" program="C:\Program Files (x86)\Embarcadero\Studio\19.0\bin\LicenceManager.exe" protocol=any dir=out enable=yes action=block profile=Private,Public,Domain
注:bds.exe、LicenceManager.exe 按照实际安装目录调整。
12、DevExpress 安装
1,把DevExpress 22.2.3(修正)解压;举例:复制到类似于这样的目录下:D:\Program Files (x86)\DevExpress 22.2.3
2.点击tools菜单,选择language下的library目录,在library path中选择D:\Program Files (x86)\DevExpress 22.2.3 添加2个地址
D:\Program Files (x86)\DevExpress 22.2.3\Library\RS28
D:\Program Files (x86)\DevExpress 22.2.3
3.运行D:\Program Files (x86)\DevExpress 22.2.3目录下的DEV自动安装程序.exe 直接安装即可;
4.再运行“注册DevExpress帮助.exe” 进行一下注册;
5.如果要看demo,就安装DevExpressVCLProductDemos-22.2.3.exe ,会在C盘下产生路径;如果不安装的话就可以看DevExpress-Demos的使用文件夹
6.如何是和源代码一起带过来的demo文件夹,好像有些问题,最好的方式是去官网下载 DevExpressVCLProductDemos-22.2.3.exe 进行安装
7.demo下载地址:https://www.devexpress.com/Products/VCL/
关于demo文件夹的使用
1.如果提示cxver.INC的错误,就在源代码下面复制一个cxver.INC的文件,放到D:\Program Files (x86)\DevExpress 22.2.3目录下
2.在delphi11中,点击project ,delphi compiler,点击search path,然后添加D:\Program Files (x86)\DevExpress 22.2.3 目录即可
13、安卓SDK更新方法
1、修改host文件:
记事本打开C:\Windows\System32\drivers\etc\host文件
末尾添加
64.233.162.83 dl.google.com
64.233.162.83 dl.l.google.com
注意:这个IP地址经常改变,需要到这个网站查询最新的IP进行替换:
http://www.360kb.com/kb/2_122.html
保存文件.
2、修改代理:开始菜单-Delphi-进入Android SDK Manager
打开菜单Tools-Options
代理地址写入mirrors.neusoft.edu.cn 端口输入 80
再下面Others里面勾选Force https://source to be fetched using http://... 确定。
如果不自动下载则主菜单Packages-Reload进行刷新下载。
---------------------------------------------------------------
*** 如果无法找到网址,请搜索:google hosts 关键词搜索网站或者脚本。
14、C++ Builder(RAD Studio)11.1代码提示问题
C++ Builder 11.1版本基于cquery的代码提示比10.3和10.4版本有了很大的改进,基本上可用了。
1、要64位Win10以上系统;
2、RAD Studio安装目录下Bin64目录里要有cquery.exe和ideclang50.dll;
3、工程要已经保存;
4、第一次使用时,要重新加载一次工程,并等cquery.exe开始大量占用CPU和内存后再开始编写代码;
5、要使用clang编译器(C++ Builder 10.3以上版本新建工程默认选项就是,10.2及以下版本新建VCL工程Win32配置默认使用经典编译器),11.1版本中Win32经典编译器的代码提示已经取消了。
旧版VCL工程Win32配置设置编译器:Project——Options——Building——C++ Compiler——C++ Compilers(WIN32),再保存工程。
15、OLE操作Excel的完整代码
#include
#include "Excel_2K_SRVR.h"
//#include "ComObj.hpp"
/*-------------------------------------------------
//谨慎的思考310032649原创文章
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString str1="asvasd";//要入库的数据
Variant ex,newxls,sh;
try{
ex=CreateOleObject("Excel.Application");//启动Excel
ex.OlePropertySet("Visible",(Variant)true);//使Excel启动后可见
//ex.OlePropertyGet("WorkBooks").OleProcedure("ADD");//新建一新工作薄(加上这一句,会有两个Excel窗口,同时关闭)
//ex.OlePropertySet("Visible",(Variant)false);//使Excel启动后不可见
//ex.OlePropertySet("Windowstate",1);//Excel启动后窗体状态:1(xlNormal)正常显示(Excel上次关闭时是什么状态,启动后就是什么状态),2(xlMinimized)最小化(不是缩小到任务栏),3(xlMaximized)最大化
newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add");//①//使用ExcelApp的Exec方法新建一有3个工作表的默认工作薄
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",1);//创建有单个工作表的工作簿
//newxls=ex.OlePropertyGet("workbooks").OleFunction("open", "c:\\123.xls");//打开已存在的文件,使用时可将上面关于新建①的那行屏蔽掉
sh=newxls.OlePropertyGet("ActiveSheet");
}catch(...){
ShowMessage("启动Excel出错,可能沒有安裝Excel");
return;
}
//Excel的警告提示:
sh.OlePropertyGet("Application").OlePropertySet("DisplayAlerts",false);//关闭Excel的警告提示,如提示保存等
//sh.OlePropertyGet("Application").OlePropertySet("DisplayAlerts",true);//打开Excel的警告提示,如提示保存等
//选择工作表:
//newxls.OlePropertyGet("Sheets", 2).OleProcedure("Select");//选择第二工作表
//sh = newxls.OlePropertyGet("ActiveSheet");//选择第二工作表
//重命名工作表:
//sh.OlePropertySet("Name", "Sheet的新名字");//重命名当前工作表
//取得工作表总数:
int nSheetCount=newxls.OlePropertyGet("Sheets").OlePropertyGet("Count");//取得工作表总数
Edit1->Text=nSheetCount;
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//新建工作表并重命名:
try{
Variant bef1,aft1;
int count=ex.OlePropertyGet("sheets").OlePropertyGet("count");
aft1=ex.OlePropertyGet("sheets",count);
ex.OlePropertyGet("sheets").OleProcedure("Add",bef1.NoParam() , aft1);
sh = ex.OlePropertyGet("ActiveSheet");
sh.OlePropertySet("Name","增加的sheet的名字");//名字不能重复
}catch(...){
//ShowMessage ("There's something wrong with your excel file./nPlease check it!");
}
//指定状态栏显示的文本:
//ex.OlePropertySet ("StatusBar","您好,请您稍等。正在查询!");//设置
//ex.OlePropertySet ("StatusBar", false);//还原成默认值
//指定标题:Exec窗口标题栏最左边显示的文本
//ex.OlePropertySet("Caption","查询系统");
//插入图片:
sh.OlePropertyGet("Shapes").OleFunction("AddPicture","c:\\123.gif",false,true,sh.OlePropertyGet("Range","B10").OlePropertyGet("Left"),sh.OlePropertyGet("Range","B10").OlePropertyGet("Top"),-1,-1);//插入图片
//使指定单元格里面的数字以文本形式存储:
sh.OlePropertyGet("Cells", 2, 2).OlePropertySet("NumberFormatLocal", "@");//使指定单元格里面的数字以文本形式存储,可以省略
//使用下划线:
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Underline",true);//在所有单元格中使用下划线
//sh.OlePropertyGet("Cells",1,1).OlePropertyGet("Font").OlePropertySet("Underline",true);//在指定单元格中使用下划线
//使用删除线:
sh.OlePropertyGet("Cells",i,1).OlePropertyGet("Font").OlePropertySet("Strikethrough",true);//在指定单元格中使用删除线
//使用斜体:
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Italic",true);//在所有单元格中使用斜体
//sh.OlePropertyGet("Cells",1,1).OlePropertyGet("Font").OlePropertySet("Italic",true);//在指定单元格中使用斜体
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//设置字体颜色:
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Color",RGB(0,0,255));//设置所有单元格的字体颜色
//sh.OlePropertyGet("Cells",1,1).OlePropertyGet("Font").OlePropertySet("ColorIndex",3);//设置指定单元格的字体颜色,这里为红色
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("ColorIndex",3);//设置所有单元格的字体颜色,这里为红色
//设置列宽度:
//sh.OlePropertyGet("Columns",3).OlePropertySet("ColumnWidth",28);//设置第3列的列宽为28
//sh.OlePropertyGet("Columns").OlePropertySet("ColumnWidth",28);//设置所有列的列宽为28
//设置行高度:
//sh.OlePropertyGet("Rows").OlePropertySet("RowHeight",28);//设置所有行的高度为28
//sh.OlePropertyGet("Rows",3).OlePropertySet("RowHeight",28);//设置指定行的高度为28
//设置字体:
//sh.OlePropertyGet("Cells", 1, 1).OlePropertyGet("Font").OlePropertySet("Name", "隶书");//设置第一行第一列单元格的字体
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Name", "隶书");//设置所有单元格的字体
//字体大小:
//sh.OlePropertyGet("Cells", 1, 1).OlePropertyGet("Font").OlePropertySet("Size",10);//设置第一行第一列单元格的字体大小为10号
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Size",10);//设置所有单元格的字体大小为10号
//使用粗体:
//sh.OlePropertyGet("Cells",1,1).OlePropertyGet("Font").OlePropertySet("Bold",true);//设置第一行第一列单元格的字体为粗体字
//sh.OlePropertyGet("Cells").OlePropertyGet("Font").OlePropertySet("Bold",true);//设置所有单元格的字体为粗体字
//插入和删除行:
//sh.OlePropertyGet("Rows", 1).OleProcedure("Insert");//在指定位置插入行
//sh.OlePropertyGet("Rows", 1).OleProcedure("Delete");//将指定的行删除
//设置单元格的数字显示格式:
//sh.OlePropertyGet("Cells", 1, 1).OlePropertySet("NumberFormatLocal", "0.00%");//设置指定单元格格式为小数百分比
//sh.OlePropertyGet("Cells").OlePropertySet("NumberFormatLocal", "0.00%");//设置所有单元格格式为小数百分比
//sh.OlePropertyGet("Rows",1).OlePropertySet("NumberFormatLocal", "0.00%");//设置指定行单元格格式为小数百分比,当不加“,1”时为所有行
//sh.OlePropertyGet("Columns",1).OlePropertySet("NumberFormatLocal", "0.00%");//设置指定列单元格格式为小数百分比,当不加“,1”时为所有列
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("NumberFormatLocal","#,##0.00");//指定单元格如果是数字就保留两位小数
//文本自动换行:
//sh.OlePropertyGet("Cells", 1, 1).OlePropertySet("WrapText", true);//设置指定单元格的文本自动换行
//sh.OlePropertyGet("Cells").OlePropertySet("WrapText", true);//设置所有单元格的文本自动换行
//sh.OlePropertyGet("Columns",1).OlePropertySet("WrapText", true);//设置指定列的单元格的文本自动换行, 当不加“,1”时为所有列
//sh.OlePropertyGet("Rows",1).OlePropertySet("WrapText", true);//设置指定行的单元格的文本自动换行, 当不加“,1”时为所有行
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//指定单元格的合并:
//String strRange ="A2:A3:C3";//指定合并的单元格的矩形范围
//sh.OlePropertyGet("Range", strRange.c_str()).OleFunction("Merge", false);//将指定的单元格合并
//sh.OlePropertyGet("Range", "A2:A3:C3").OleFunction("Merge", false);//将指定的单元格合并
//给单元格赋值:
//sh.OlePropertySet("Cells","第 &P 頁,共 &N 頁");//给所有单元格赋值
sh.OlePropertyGet("Cells",1,1).OlePropertySet( "Value",str1.c_str());//给指定单元格赋值
//sh.OlePropertyGet("Rows",1).OlePropertySet("Value",1234);//给整个行的单元格赋值
//sh.OlePropertyGet("Columns",1).OlePropertySet("Value",1234);//给指定的整个列赋值
//从单元格中取值:
//AnsiString abc=sh.OlePropertyGet("Cells",1,1).OlePropertyGet("Value");//取指定单元格的值
//选择单元格:
//sh.OlePropertyGet("Cells").OleFunction("Select");//选择所有单元格
//sh.OlePropertyGet("Cells",3,3).OleFunction("Select");//选择指定单元格(指定的单元格获得焦点)
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//区域操作:
//sh.OlePropertyGet("Range","A1:A10");//创建区域对象
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Cells").OlePropertySet("Value",10);//给指定区域的单元格赋值
//sh.OlePropertyGet("Range","A1:A10").OlePropertyGet("Cells").OleFunction("Select");//选中指定区域的单元格
//sh.OlePropertyGet("Range","A1:A10").OlePropertyGet("Font").OlePropertySet("Name", "隶书");//设置指定区域中所有单元格的字体
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Font").OlePropertySet("Underline",true);//设置指定区域的所有单元格中使用下划线
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Font").OlePropertySet("Italic",true);//设置指定区域中所有单元格中使用斜体
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Font").OlePropertySet("Color",RGB(0,0,255));//设置所有单元格的字体颜色
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Font").OlePropertySet("Size",10);//设置指定区域中所有单元格字体的大小为10号
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Font").OlePropertySet("Bold",true);//设置指定区域中所有单元格的字体为粗体字
//sh.OlePropertyGet("Range","A1:C10").OleProcedure("Insert");//在指定区域前面增加指定列的单元格,指定区域外不受影响
//sh.OlePropertyGet("Range","A1:C10").OleProcedure("Delete");//将指定的行删除
//sh.OlePropertyGet("Range","A1:C10").OlePropertySet("NumberFormatLocal", "0.00%");//设置指定区域中的所有单元格格式为小数百分比
//sh.OlePropertyGet("Range","A1:C10").OlePropertySet("WrapText", true);//设置指定区域中所有的单元格中的文本自动换行
//sh.OlePropertyGet("Range","A1:C10").OlePropertySet("ColumnWidth",28);//设置指定区域所包含的所有列的列宽为28
//sh.OlePropertyGet("Range","A1:C10").OlePropertySet("RowHeight",28);//设置指定区域所包含的所有行的高度为28
//sh.OlePropertyGet("Range","A1:C20").OlePropertySet("DirectDependents","sdasd");//将选定区域中所有含公式的单元格填充成指定值,"sdasd"可以替换成不加引号的TRUE等
//单元格中的数据计算:
//sh.OlePropertyGet("Cells",5,6).OlePropertySet("FormulaR1C1","=SUM(R[-3]C:R[-1]C)");//竖排加法运算
//sh.OlePropertyGet("Cells",2,9).OlePropertySet("FormulaR1C1","=SUM(RC[-3]:RC[-1])");//横向加法运算
//sh.OlePropertyGet("Cells",5,8).OlePropertySet("FormulaR1C1","=SUM(R[-3]C[-2]:R[-1]C[-1])");//横竖向加法运算
//页眉页脚设置:打印预览才能看见
sh.OlePropertyGet("PageSetup").OlePropertySet("LeftHeader","sdfgs");//左上角页眉设置
sh.OlePropertyGet("PageSetup").OlePropertySet("CenterHeader","sadfs");//中间页眉设置
sh.OlePropertyGet("PageSetup").OlePropertySet("RightHeader","345s");//右上角页眉设置
sh.OlePropertyGet("PageSetup").OlePropertySet("LeftFooter","234fasdf");//左下角页脚设置
sh.OlePropertyGet("PageSetup").OlePropertySet("CenterFooter","第 &P 页,共 &N 页");//中间页脚设置(这里显示第几页,共几页)
sh.OlePropertyGet("PageSetup").OlePropertySet("RightFooter","sd23");//右下脚页角设置
//边界设定:单位为:point , 一 point = 1 / 72 inches
//sh.OlePropertyGet("PageSetup").OlePropertySet("LeftMargin",15);
//sh.OlePropertyGet("PageSetup").OlePropertySet("RightMargin",15);
//sh.OlePropertyGet("PageSetup").OlePropertySet("TopMargin",15);
//sh.OlePropertyGet("PageSetup").OlePropertySet("BottomMargin",15);
//sh.OlePropertyGet("PageSetup").OlePropertySet("HeaderMargin",15);
//sh.OlePropertyGet("PageSetup").OlePropertySet("FooterMargin",15);
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//打印设定:
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintTitleRows","$2:$2");//打印标题列
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintTitleColumns","$A:$A");//打印标题栏
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintArea","$A$1:$I$15");//打印范围
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintHeadings",false);//栏名列号
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintGridlines",false);//打印网格线
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintComments",xlPrintNoComments);//批注"无"
//sh.OlePropertyGet("PageSetup").OlePropertySet("PrintQuality",300);//打印品质
//sh.OlePropertyGet("PageSetup").OlePropertySet("CenterHorizontally",true);//水平置中
//sh.OlePropertyGet("PageSetup").OlePropertySet("CenterVertically",false);//垂直置中
//sh.OlePropertyGet("PageSetup").OlePropertySet("Orientation",xlLandscape);//横向打印 (xlPortrait 纵向打印)
//sh.OlePropertyGet("PageSetup").OlePropertySet("Draft",false);//草稿品质
//sh.OlePropertyGet("PageSetup").OlePropertySet("PaperSize",xlPaperA4);//纸张大小
//sh.OlePropertyGet("PageSetup").OlePropertySet("FirstPageNumber",xlAutomatic);//起始页码
//sh.OlePropertyGet("PageSetup").OlePropertySet("Order",xlDownThenOver);//循栏打印 (xlOverThenDown 循列打印)
//sh.OlePropertyGet("PageSetup").OlePropertySet("BlackAndWhite",False);//储存格单色打印
//sh.OlePropertyGet("PageSetup").OlePropertySet("Zoom",100);//缩放比例
//设定单元格背景色:
//sh.OlePropertyGet("Cells",2,2).OlePropertyGet("Interior").OlePropertySet("ColorIndex",3);//设定指定单元格的背景色
//设定图样:xlGray50可以是1,2,3等数字
//sh.OlePropertyGet("Cells",4,2).OlePropertyGet("Interior").OlePropertySet("Pattern",xlGray50);
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Interior").OlePropertySet("Pattern",xlGray50);//在指定区域设置图样
//设置单元格中的文字距左:
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("HorizontalAlignment",xlLeft);//设置单元格中的文字距左
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("VerticalAlignment",xlCenter);//作用不明(垂直和水平居中?)
//设置单元格中的文字距中:
sh.OlePropertyGet("Cells",1,1).OlePropertySet("HorizontalAlignment",xlCenter);//设置单元格中的文字距中
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("VerticalAlignment",xlCenter);//作用不明
//设置单元格中的文字距右:
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("HorizontalAlignment",xlRight);//设置单元格中的文字距右
//sh.OlePropertyGet("Cells",1,1).OlePropertySet("VerticalAlignment",xlCenter);//作用不明
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
//工作表操作:
//sh.OlePropertySet("Name", "Sheet的新名字");//重命名当前工作表
//sh.OleFunction("Delete");//删除当前工作表
//画单元格单条边框:
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeLeft).OlePropertySet("Weight",xlThin);//画单元格左边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeLeft).OlePropertySet("LineStyle",xlContinuous);//画单元格左边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeRight).OlePropertySet("Weight",xlThin);//画单元格右边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeRight).OlePropertySet("LineStyle",xlContinuous);//画单元格右边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeTop).OlePropertySet("Weight",xlThin);//画单元格上边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeTop).OlePropertySet("LineStyle",xlContinuous);//画单元格上边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeBottom).OlePropertySet("Weight",xlThin);//画单元格下边框
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertyGet("Item",xlEdgeBottom).OlePropertySet("LineStyle",xlContinuous);//画单元格下边框
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Borders").OlePropertyGet("Item",xlDiagonalDown).OlePropertySet("Weight",4);//将指定区域的单元格用粗实线划掉
//画单元格完整边框:
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Borders").OlePropertySet("linestyle",2);//给指定区域的所有单元格加上边框,最后的数字:1=细实线框,2=短距虚线框,3=长距虚线框,4=点划线,5=双点划线,6=粗点划线
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Borders").OlePropertySet("weight",1);//给指定区域的所有单元格加上边框,最后的数字不大于4
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Borders").OlePropertySet("colorindex",3);//给指定区域的所有单元格加上边框,最后的数字表示颜色
//sh.OlePropertyGet("Cells",11,2).OlePropertyGet("Borders").OlePropertySet("LineStyle",xlContinuous);//给指定单元格四周加上实线边框
//去掉指定区域的边框:
//sh.OlePropertyGet("Range","A1:C10").OlePropertyGet("Borders").OlePropertySet("linestyle",xlNone);//去掉指定区域的边框
//画单元格单面边框参数说明:
//xlDiagonalDown:绘制从左上到右下角的斜线
//xlDiagonalUp:绘制从左下到右上角的斜线
//xlEdgeBottom:画单元格下边框
//xlEdgeLeft:画单元格左边框
//xlEdgeRight:画单元格右边框
//xlEdgeTop:画单元格上边框
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
try{
//sh.OleFunction("SaveAs", "c:\\123.xls");//保存工作簿,当文件已经存在时会有提示,如果不覆盖会出错,所以正式使用时要预先处理或拦截错误
//sh.OleFunction("SaveAs", WideString("c:\\"+ADODataSet1->FieldByName("creater")->AsString.Trim()+".xls"));//保存工作簿,当文件已经存在时会有提示,如果不覆盖会出错,所以正式使用时要预先处理或拦截错误
//newxls.OleFunction("Close");//关闭表格
//ex.OleFunction("Quit");//退出Excel,释放OLE对象
}catch(...){
return;
}
//结束,如果没有如下代码,EXCEL线程直到应用程序退出才结束:
Variant Axl,Workbook,AxSheet,nms,bef,aft;
Axl=Unassigned;
Workbook=Unassigned;
AxSheet=Unassigned;
bef=Unassigned;
aft=Unassigned;
nms=Unassigned;
//ShowMessage("Well Done boy!");//弹出对话框
}
//图表部分,备用:------------------------------
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
1)
//开一个新的图表工作簿
Variant Chart;
Chart = ex.Exec(PropertyGet("Charts")).Exec(Function("Add"));
ex.Exec(PropertySet("Visible") << true);
Chart.Exec(PropertySet("Type") << -4100);
2)
//滚动图表
for(int nRotate=5; nRotate <= 180; nRotate += 5){
Chart.Exec(PropertySet("Rotation") << nRotate);
}
for(int nRotate = 175; nRotate >= 0; nRotate -= 5){
Chart.Exec(PropertySet("Rotation") << nRotate);
}
/*-------------------------------------------------
//目前真正最全的OLE操作Excel的完整代码
//版本:2007.01.15.01
//C++Builder专家组www.3322ee.com原创文章
//转载请保留本版权信息,谢谢合作
--------------------------------------------------/
3)
//使用ExcelApp的Exec方法新建一新工作薄
newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add");//默认工作簿
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",1);//单工作表
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",2);//图表
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",3);//宏表
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",4);//国际通用宏表
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",5);//与默认的相同
//newxls=(ex.OlePropertyGet("Workbooks")).OleFunction("Add",6);//工作簿且只有一个表
16、串口波特率的概念
波特率115200 = 115200 (位/秒) = 10.27 (KB/秒)。
波特率的计算公式如下:
波特率 = F / [16 X (256 – UARTBAUD ) ]
波特率 波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,其单位为波特(Baud)。
比特率在数值上和波特率有这样的关系:
波特率与比特率的关系为:比特率=波特率X单个调制状态对应的二进制位数。
波特率115200 = 115200(位/秒) = 10.27 (KB/秒)。
115200/8=14400字节(1秒)
5M bit/s
5000000/8 = 625000字节/s
610kb/s
0.6M/s
以波特率115200为例:
115200kbit/s表示的是串口每秒钟可以传输115200kbits,那么每传输1bit所需时间:1s / 115200kbits = 1 * 10e9 / 115200 * 10e3 = 1000/115.2 = 8.6806us;
14400字节/s 15kb/s
要求: 5000000kbit
STM32串口1最高波特率: 4500000 kbit
562500字节/s 550kb/s
波特率115200 = 115200 (位/秒)。
如果没有校验位,就应该除以 10,得到的是每秒字节数:波特率115200 = 115200 (位/秒) = 11520 (字节/秒)。
再除以 1024,就是每秒 KB 数:波特率115200 = 115200 (位/秒) = 11.25 (KB/秒)。如果有一位奇偶校验位,就应该除以 11,得到的是每秒字节数。
最后得出:波特率115200 = 115200 (位/秒) = 10.27 (KB/秒)。
如果串口没有校验位,起始位+停止位+8为数据=10位
115200bit/s--->115200/10--->11520byte/s ---->11520/1024---->11.25kb/s--->0.01M/s
5000000bit/s-->5000000/10--->500000byte/s--->500000/1024--->488.28125kb/s--->0.47M/s
STM32 串口1的最高波特率可达到:4500000bit/s
波特率115200 = 115200 (位/秒)
如果没有校验位,就应该除以 10,得到的是每秒字节数:
波特率115200 = 115200 (位/秒) = 11520 (字节/秒)
再除以 1024,就是每秒 KB 数:
波特率115200 = 115200 (位/秒) = 11.25 (KB/秒)
============================
如果有一位奇偶校验位,就应该除以 11,得到的是每秒字节数。
最后:
波特率115200 = 115200 (位/秒) = 10.27 (KB/秒)
BPS,是指比特率。按照大小写分类可以指Bps、bps、BPS
17、未完待续。。。