定位控件可以分为两个部分:
展示部分:包括展示定位图片、定位标题、定位地址;
数据部分:当前地址纬度(latitude)、经度(longitude);
以下为LocationOle控件的头文件部分:
extern "C" const GUID IID_LocationOleCtrl;
class RichEditLocationOle :public RichEditOleBase
{
DECLARE_REOBJ(RichEditLocationOle, L"location")
public:
RichEditLocationOle();
~RichEditLocationOle();
BOOL InitOleWindow(IRichEditObjHost* pHost);
SStringW GetLocationId(){return GetId();}
SStringW GetLongitude(){return _location_longitude;}
SStringW GetLatitude(){return _location_latitude;}
protected:
void UpdatePosition();
bool OnBnClickLocation(SOUI::EventArgs* pEvt);
protected:
SOUI_ATTRS_BEGIN()
ATTR_STRINGW(L"location_imgpath", _location_imgpath, FALSE)
ATTR_STRINGW(L"location_title", _location_title, FALSE)
ATTR_STRINGW(L"location_address", _location_address, FALSE)
ATTR_STRINGW(L"location_longitude", _location_longitude, FALSE)
ATTR_STRINGW(L"location_latitude", _location_latitude, FALSE)
SOUI_ATTRS_END()
private:
SStringW _location_imgpath; //地图展示图片
SStringW _location_title; //定位地名
SStringW _location_address; //定位地址
SStringW _location_longitude; //经度
SStringW _location_latitude; //纬度
};
以下为LocationOle控件的源文件部分:
static const GUID IID_LocationOleCtrl =
{ 0x6eb0418, 0xbd55, 0x49e0, { 0x95, 0x2a, 0xae, 0x86, 0x15, 0x2b, 0x94, 0xf7 } };
RichEditLocationOle::RichEditLocationOle()
{
_oleGuid = IID_LocationOleCtrl;
_sizeNatural.cx = 265;
_sizeNatural.cy = 150;
_canBeSelect = FALSE;
_xmlLayout = L"LAYOUT:LocationOleLayout";
}
RichEditLocationOle::~RichEditLocationOle()
{
}
BOOL RichEditLocationOle::InitOleWindow(IRichEditObjHost* pHost)
{
BOOL bRet = RichEditOleBase::InitOleWindow(pHost);
IBitmap* pLocationImg = SResLoadFromFile::LoadImage(_location_imgpath);
SImageWnd* pLocationImgWnd = _oleView.FindChildByName2<SImageWnd>(L"location_img");
if (pLocationImg && pLocationImgWnd)
{
pLocationImgWnd->SetImage(pLocationImg);
UpdateWindowLayout(pLocationImgWnd);
}
SStatic* pLocationTitle = _oleView.FindChildByName2<SStatic>(L"location_title");
if (pLocationTitle)
{
pLocationTitle->SetWindowText(_location_title);
UpdateWindowLayout(pLocationTitle);
}
SStatic* pLocationAddress = _oleView.FindChildByName2<SStatic>(L"location_address");
if (pLocationAddress)
{
pLocationAddress->SetWindowText(_location_address);
UpdateWindowLayout(pLocationAddress);
}
SWindow* pLocationWnd = _oleView.FindChildByName2<SWindow>(L"locationwnd");
if (pLocationWnd)
{
SUBSCRIBE(pLocationWnd, EVT_CMD, RichEditLocationOle::OnBnClickLocation);
}
return bRet;
}
bool RichEditLocationOle::OnBnClickLocation(SOUI::EventArgs* pEvt)
{
_pObjHost->NotifyRichObjEvent(this, CLICK_LOCATION_OLE, 0, 0);
return true;
}
void RichEditLocationOle::UpdatePosition()
{
if (_spAdviseSink)
{
_oleView.SetOleWindowRect(CRect(0, 0, 0, 0)); // 已经失效
_oleView.Move(0, 0, _sizeNatural.cx, _sizeNatural.cy);
CalculateExtentSize(_sizeNatural);
_spAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
}
}
IID_LocationOleCtrl为控件GUID,可以自己生成。
接口说明:
InitOleWindow:初始化Ole窗口
GetLongitude:获取经度
GetLatitude:获取纬度
GetLocationId:获取元素ID
OnBnClickLocation:定位控件点击事件
以下是控件布局相关XML:
<root>
<window name="locationwnd" pos="0,0,-0,-0" cursor="hand" >
<text name="location_title" cursor="hand" pos="5,0,@230,@15" dotted="1" align="left" colorText="#000000" font="size:14" />
<text name="location_address" cursor="hand" pos="5,[5,@230,@13" dotted="1" align="left" colorText="#7F7F7F" font="size:12" />
<img name="location_img" pos="5,[10,-0,-0" cursor="hand"/>
</window>
</root>
控件需要在uires.idx文件中添加相关映射关系
注意事项跟《拓展SOUI中SImRichEdit控件的语音OLE控件(AudioOle)》中一样;
以下为使用示例代码:
SStringW strLocation;
std::string strLocationId = KfUtility::GenerateUUID();
std::wstring wstrLocationId;
KfUtility::ConvertUtf8ToUtf16(strLocationId, wstrLocationId);
SStringW strLocationImgPath = L"D:\\imrepose\\trunk\\KFClient6\\output\\Debug_Unicode\\default_res\\location.jpg";
SStringW strLocationTitle = L"食尚中式快餐(紫萱路)";
SStringW strLocationAddress = L"五里堂街与紫萱路交叉口东南100米";
SStringW strLongitude = L"120.074631";
SStringW strLatitude = L"30.316891";
strLocation.Format(L"<location id=\"%s\" location_imgpath=\"%s\" location_title=\"%s\" location_address=\"%s\" location_longitude=\"\" location_latitude=\"%s\" />",
wstrAudioId.c_str(),
strLocationImgPath,
strLocationTitle,
strLocationAddress,
strLongitude,
strLatitude);
SStringW strContentLocation;
strContentLocation.Format(
L"<RichEditContent type=\"ContentRight\" align=\"right\" auto-layout=\"1\">"
L"<para break=\"1\" align=\"left\" />"
L"<bkele data=\"avatar\" id=\"%s\" skin=\"%s\" left-pos=\"0,]-6,@40,@40\" right-pos=\"-50,]-10,@40,@40\" cursor=\"hand\" interactive=\"1\"/>"
L"<para id=\"msgbody\" margin=\"65,0,45,0\" break=\"1\" simulate-align=\"1\">"
L"%s"
L"</para>"
L"<bkele data=\"bubble\" left-skin=\"skin_left_bubble\" right-skin=\"skin_right_otherbubble\" left-pos=\"50,{-9,[10,[10\" right-pos=\"{-10,{-9,-55,[10\" />"
L"%s"
L"</RichEditContent>",
wstrId.c_str(), wstrFaceId.c_str(), strLocation, pEmpty);
pRecvRichEdit->InsertContent(strContentLocation, RECONTENT_LAST);
效果图如下:
以下为定位控件点击事件处理,通过浏览器打开高德地图:
case CLICK_LOCATION_OLE:
{
RichEditLocationOle* pLocationOle = sobj_cast<RichEditLocationOle>(pev->RichObj);
if (pLocationOle)
{
SStringW strLongitude = pLocationOle->GetLongitude();
SStringW strLatitude = pLocationOle->GetLatitude();
SStringW strUrl;
strUrl.Format(L"http://uri.amap.com/marker?position=%s,%s", strLongitude, strLatitude);
ShellExecute(NULL, L"open",strUrl, NULL,NULL,SW_SHOWNORMAL);
}
}
break;