零基础开发powerbuilder界面

本文仅限零基础开发powerbuilder简单界面以及加载DLL函数,并不涉及powerbuilder的基础学习,也未涉及应用数据库,以入门的请越过此文。

好记性不如烂笔头,更不用说记性差了!写作本文就是为了把网上零散的内容结合实际开发整理一下,方便以后需要的时候随时可以参考。本次测试使用的是powerbuilder12.6版。

主要内容是使用c++开发一个DLL功能模块提供给powerbuilder开发使用。使用c++开发给pb使用的dll,对函数的导出需要指定为__stdcall并且需要写def模块定义文件。在这里主要测试基础参数类型在pb中的使用。

c++头文件pbdll.h

#pragma once

bool __stdcall setBool(bool v);
bool __stdcall getBool();
char __stdcall setChar(char v);
char __stdcall getChar();
short __stdcall setShort(short v);
short __stdcall getShort();
int __stdcall setInt(int v);
int __stdcall getInt();
long long __stdcall setLong(long long v);
long long __stdcall getLong();
float __stdcall setFloat(float v);
float __stdcall getFloat();
double __stdcall setDouble(double v);
double __stdcall getDouble();
const char* __stdcall setString(const char* v);
const char* __stdcall getString();
int __stdcall setImage(const unsigned char* v, int size);
const char* __stdcall getImage();
const char* __stdcall getNull();

c++源码文件pbdll.cpp

#include "pbdll.h"
#include <stdio.h>
#include <io.h>
#include <string>

template<class... _Args>
void LOG(const char* fmt, _Args&&... args)
{
	FILE* fp = fopen("c:/pblog.txt", "at+");
	if (fp)
	{
		fprintf(fp, fmt, std::forward<_Args>(args)...);
		fclose(fp);
	}
}

static bool bv = false;
bool __stdcall setBool(bool v)
{
	LOG("bool=%d\n", v);
	bool r = bv;
	bv = v;
	return r;
}
bool __stdcall getBool()
{
	return bv;
}

static char cv = 'P';
char __stdcall setChar(char v)
{
	LOG("char=%d\n", v);
	char r = cv;
	cv = v;
	return r;
}
char __stdcall getChar()
{
	return cv;
}

static short sv = 0x1234;
short __stdcall setShort(short v)
{
	LOG("short=%d\n", v);
	short r = sv;
	sv = v;
	return r;
}
short __stdcall getShort()
{
	return sv;
}

static int iv = 0x12345678;
int __stdcall setInt(int v)
{
	LOG("int=%d\n", v);
	int r = iv;
	iv = v;
	return r;
}
int __stdcall getInt()
{
	return iv;
}

static long long llv = 0x1234567812345678;
long long __stdcall setLong(long long v)
{
	LOG("long=%lld\n", v);
	long long r = llv;
	llv = v;
	return r;
}
long long __stdcall getLong()
{
	return llv;
}

static float fv = 9.123;
float __stdcall setFloat(float v)
{
	LOG("float=%f\n", v);
	float r = fv;
	fv = v;
	return r;
}
float __stdcall getFloat()
{
	return fv;
}

static double dv = 3.1415926;
double __stdcall setDouble(double v)
{
	LOG("double=%lf\n", v);
	double r = dv;
	dv = v;
	return r;
}
double __stdcall getDouble()
{
	return dv;
}

static std::string str = "hello";
std::string r;
const char* __stdcall setString(const char* v)
{
	LOG("string=%s\n", v);
	r = str;
	str = v;
	return r.c_str();
}
const char* __stdcall getString()
{
	return str.c_str();
}

int __stdcall setImage(const unsigned char* v, int size)
{
	if (size)
	{
		FILE* fp = fopen("c:/pbt", "wb");
		if (fp)
		{
			size_t r = fwrite(v, 1, size, fp);
			fclose(fp);
			return r;
		}
		return -1;
	}
	return 0;
}

const char* __stdcall getImage()
{
	return "c:/pbt";
}

const char* __stdcall getNull()
{
	return 0;
}

再新建一个pbdll.def文件

LIBRARY "pbdll"
      DESCRIPTION 'pbdll Windows Dynamic Link Library'
      EXPORTS
      ; Explicit exports can go here
      setBool 
	  getBool
      setChar
	  getChar
	  setShort
	  getShort
	  setInt
	  getInt
	  setLong
	  getLong
	  setFloat
	  getFloat
	  setDouble
	  getDouble
	  setString
	  getString
	  setImage
	  getImage
	  getNull

编译生成一个pbdll.dll备用。

首先学习下Powerscript语言基础:https://blog.csdn.net/gyming/article/details/7883722#comments

然后了解下powerbuilder开发工具:https://wenku.baidu.com/view/a536f517dc36a32d7375a417866fb84ae45cc3ee.html

建立demo工程:

1.在你要创建工程的目录下新建该工程保存的文件夹。

2.new一个workspace,再new一个Target,选择Application。

demo

3.new一个PB Object,选择window,设置好属性(随时都可以更改),Ctrl+S保存。

w_main

window

4.双击demo,实现demo的open事件,写上一句open(w_main)。

opendemo

或者展开Events,双击open

openmain2

导入dll中的函数,选择(Declare)——Global External Functions

function

其中getABC为dll中不存在的函数,ALIAS FOR "***;ANSI"表示字符串为ANSI编码,低版本的powerbuilder不需要加,具体根据dll的编码情况和powerbuilder的版本而定。

5.双击w_main(即新建的window)返回窗口,可以看到也有一个open事件,在这里可以做一些窗口初始化工作。切换到Layout标

Dialog

如果需要在退出的时候做提示,可以切换到open标签,选择closequery事件并添加如下代码

closequery

6.拖控件,控件在菜单“Insert”——“Control”查看所有控件

kj

在这里测试如下功能

layout

对应的控件名称,其中Picture控件取消OriginalSize属性

bool类型st_boolsle_boolsle_bool2
8 bit整数st_charsle_charsle_char2
16 bit整数st_shortsle_short

sle_short2

32 bit整数st_intsle_intsle_int2
64 bit整数st_longsle_longsle_long2

单精度浮点数

st_floatsle_floatsle_float2
双精度浮点数st_doublesle_doublesle_double2
char*字符串st_stringsle_stringsle_string2
文件p_1cb_1(按钮)p_2

右边可以设置控件的属性、字体、显示位置大小等,左边可以批量调整控件对齐方式

dq

7.双击test按钮,为clicked事件添加如下代码

if pb_getBool() then
	pb_setBool(false)
else
	pb_setBool(true)
end if
setChar(char(sle_char.text))
setShort(integer(sle_short.text))
setInt(long(sle_int.text))
setLong(longlong(sle_long.text))
setFloat(real(sle_float.text))
setDouble(double(sle_double.text))
setString(sle_string.text)

sle_bool2.text = string(pb_getBool())
sle_char2.text = string(getChar())
sle_short2.text = string(getShort())
sle_int2.text = string(getInt())
sle_long2.text = string(getLong())
sle_float2.text = string(getFloat())
sle_double2.text = string(getDouble())
sle_string2.text = getString()

if sle_char.text <> sle_char2.text then
	sle_char2.backcolor = RGB(255, 0, 0)
else
	sle_char2.backcolor = sle_char.backcolor
end if

if sle_short.text <> sle_short2.text then
	sle_short2.backcolor = RGB(255, 0, 0)
else
	sle_short2.backcolor = sle_short.backcolor
end if

if sle_int.text <> sle_int2.text then
	sle_int2.backcolor = RGB(255, 0, 0)
else
	sle_int2.backcolor = sle_int.backcolor
end if

if sle_long.text <> sle_long2.text then
	sle_long2.backcolor = RGB(255, 0, 0)
else
	sle_long2.backcolor = sle_long.backcolor
end if

if sle_float.text <> sle_float2.text then
	sle_float2.backcolor = RGB(255, 0, 0)
else
	sle_float2.backcolor = sle_float.backcolor
end if

if sle_double.text <> sle_double2.text then
	sle_double2.backcolor = RGB(255, 0, 0)
else
	sle_double2.backcolor = sle_double.backcolor
end if

if sle_string.text <> sle_string2.text then
	sle_string2.backcolor = RGB(255, 0, 0)
else
	sle_string2.backcolor = sle_string.backcolor
end if

string path = 'c:/'
string name = '1'

string fn, fne
fn = path + name
if FileExists(fn) then
	fne = fn
else
	fne = fn + ".bmp"
end if

if not FileExists(fne) then
	fne = fn + ".jpg"
end if

if not FileExists(fne) then
	fne = fn + ".png"
end if

int fp
blob fdata
if FileExists(fne) then	
	fp = FileOpen(fne, streammode!,read!,lockread!)	
	int rs
	do
		blob frd
		rs = FileRead(fp, frd)
		if rs > 0 then
			fdata = fdata + frd
		end if
	loop while rs > 0 
	FileClose(fp);
	long fsize
	fsize = len(fdata)
	if fsize > 0 then
		p_1.setPicture(fdata)
		setImage(fdata, fsize)
	end if
else
	p_1.picturename = ""
end if

string cfile
cfile = getImage()
if FileExists(cfile) then
	fp = FileOpen(fne, streammode!,read!,lockread!)
	FileReadEx(fp, fdata)
	FileClose(fp);
	if not isNull(fdata) then
		p_2.setPicture(fdata)
	end if
else
	p_2.picturename = ""
end if

try
	cfile = getNull()
	if isNull(cfile) then
		MessageBox('getNull','空')
	elseif len(cfile) = 0 then
		MessageBox('getNull','长度为0')
	else
		MessageBox('getNull',cfile)
	end if
catch(RunTimeError e)
	MessageBox('getNull',e.text)
end try

try
	getABC()
catch(RunTimeError e1)
	MessageBox('getABC',e1.text)
end try

8.切换到w_main——open事件,添加初始化控件代码

sle_bool.text = string(pb_getBool())
sle_char.text = string(getChar())
sle_short.text = string(getShort())
sle_int.text = string(getInt())
sle_long.text = string(getLong())
sle_float.text = string(getFloat())
sle_double.text = string(getDouble())
sle_string.text = getString()

9.点击Run运行

r1

可以看到float类型有尾巴问题。修改各项后点击test按钮,会依次弹出如下消息框

getnullgetABC

证明不存在的函数会报runtime错误,最后的结果如图

r2

进一步证明float类型的传递有问题。

总结:对于基本数据类型要注意c++的取值范围与pb的取值范围区别,对于浮点型数据最好转换成字符串进行传值,c++提供的dll不要使用指针类型(char*除外)。遇到pb里不懂的函数事件等首先查帮助文档,通过索引或搜索可以方便的找到要查的内容。

最后,生成exe文件:https://blog.csdn.net/tianwailaibin/article/details/8239583

【图书目录】 第1章 PB 9.0编程基础 1.1 PB 9.0的特性 1.2 PB 9.0开发环境 1.3 PB 9.0的主要画板 1.4 PowerScript简介 1.5 SQL语句的使用 1.6 常用控件 1.7 数据窗口对象 1.8 小结 第2章 记事本应用系统 2.1 应用程序的创建 2.2 窗口的创建 2.3 菜单的创建 2.4 各对象脚本的编写 2.5 应用程序的调试 第3章 同学录管理系统 3.1 系统需求分析 3.2 数据库的创建 3.3 数据库设计 3.4 各对象的创建 3.5 各对象脚本的编写 3.6 应用程序的编译和运行 3.7 小结 第4章 设备管理信息系统 4.1 系统需求分析 4.2 数据库设计 4.3 应用对象的创建 4.4 各功能模块的实现 4.5 小结 第5章 人事管理系统 5.1 系统设计 5.2 数据库设计 5.3 数据库的实现 5.4 应用程序对象的创建 5.5 全局变量和全局函数的定义 5.6 各对象的设计及脚本编写 5.7 应用程序的运行 5.8 小结 第6章 项目管理系统 6.1 系统设计 6.2 数据库设计 6.3 数据库的实现 6.4 应用程序对象的创建 6.5 全局函数和结构的定义 6.6 各对象的设计及其脚本的编写 6.7 应用程序的运行 6.8 小结 第7章 ftp文件传输系统 7.1 系统设计 7.2 数据库设计 7.3 数据库的实现 7.4 ftp的发布 7.5 应用对象的创建 7.6 全局变量和全局外部函数的定义 7.7 各对象的设计及其脚本的编写 7.8 应用程序的运行 7.9 小结 第8章 数据转换程序 8.1 实例概述 8.2 各对象的设计及其脚本的编写 8.3 应用程序的运行 8.4 小结 第9章 进销存管理系统 9.1 系统设计 9.2 数据库设计 9.3 数据库的实现 9.4 应用对象的创建 9.5 全局变量和结构的定义 9.6 各对象的设计及其脚本的编写 9.7 应用程序的运行 9.8 小结
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值