Compare commits
16 Commits
b4f37273f2
...
724586c390
Author | SHA1 | Date |
---|---|---|
|
724586c390 | 1 year ago |
|
d42e6086dc | 1 year ago |
|
5d2a15ac00 | 1 year ago |
|
96915c4f22 | 1 year ago |
|
db39095cf9 | 1 year ago |
|
be763065c4 | 1 year ago |
|
ddc735f288 | 1 year ago |
|
a6b43bc244 | 1 year ago |
|
6bc86a9fa5 | 1 year ago |
|
69dddb0523 | 1 year ago |
|
9d098db131 | 1 year ago |
|
1a73027e7d | 1 year ago |
|
4db5af56f6 | 1 year ago |
|
c2c055de4b | 1 year ago |
|
9931711153 | 1 year ago |
|
fb7f774089 | 1 year ago |
@ -0,0 +1,5 @@
|
|||||||
|
.deveco/**
|
||||||
|
.vscode/**
|
||||||
|
**/.DS_Store
|
||||||
|
.remote-sync.json
|
||||||
|
.ftpconfig*
|
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -1,679 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* FileName : CatchScreenDlg.cpp
|
|
||||||
* Author : Unknown
|
|
||||||
* Mender : sudami
|
|
||||||
* Time : 2007/09/09
|
|
||||||
*
|
|
||||||
* Comment :
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "Screenshot.h"
|
|
||||||
#include "CatchScreenDlg.h"
|
|
||||||
|
|
||||||
#include <GdiPlus.h>
|
|
||||||
using namespace Gdiplus;
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#define new DEBUG_NEW
|
|
||||||
#undef THIS_FILE
|
|
||||||
static char THIS_FILE[] = __FILE__;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// CCatchScreenDlg dialog
|
|
||||||
|
|
||||||
CCatchScreenDlg::CCatchScreenDlg(CWnd* pParent /*=NULL*/)
|
|
||||||
: CDialog(CCatchScreenDlg::IDD, pParent)
|
|
||||||
{
|
|
||||||
m_bLBtnDown = FALSE;
|
|
||||||
//初始化像皮筋类,新增的resizeMiddle 类型
|
|
||||||
m_rectTracker.m_nStyle = CMyTracker::resizeMiddle | CMyTracker::solidLine;
|
|
||||||
m_rectTracker.m_rect.SetRect(-1, -2, -3, -4);
|
|
||||||
//设置矩形颜色
|
|
||||||
m_rectTracker.SetRectColor(RGB(10, 100, 130));
|
|
||||||
|
|
||||||
m_hCursor = AfxGetApp()->LoadCursor(IDC_CURSOR1);
|
|
||||||
|
|
||||||
m_bDraw = FALSE;
|
|
||||||
m_bFirstDraw = FALSE;
|
|
||||||
m_bQuit = FALSE;
|
|
||||||
m_bNeedShowMsg = FALSE;
|
|
||||||
m_startPt = 0;
|
|
||||||
|
|
||||||
//获取屏幕分辩率
|
|
||||||
m_xScreen = GetSystemMetrics(SM_CXSCREEN);
|
|
||||||
m_yScreen = GetSystemMetrics(SM_CYSCREEN);
|
|
||||||
|
|
||||||
//截取屏幕到位图中
|
|
||||||
CRect rect(0, 0, m_xScreen, m_yScreen);
|
|
||||||
m_hBitmap = CopyScreenToBitmap(&rect);
|
|
||||||
m_pBitmap = CBitmap::FromHandle(m_hBitmap);
|
|
||||||
|
|
||||||
//初始化刷新窗口区域 m_rgn
|
|
||||||
m_rgn.CreateRectRgn(0, 0, 50, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::DoDataExchange(CDataExchange* pDX)
|
|
||||||
{
|
|
||||||
CDialog::DoDataExchange(pDX);
|
|
||||||
DDX_Control(pDX, IDC_EDIT1, m_tipEdit);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CCatchScreenDlg, CDialog)
|
|
||||||
ON_WM_PAINT()
|
|
||||||
ON_WM_MOUSEMOVE()
|
|
||||||
ON_WM_LBUTTONDOWN()
|
|
||||||
ON_WM_LBUTTONUP()
|
|
||||||
ON_WM_LBUTTONDBLCLK()
|
|
||||||
ON_WM_ERASEBKGND()
|
|
||||||
ON_WM_SETCURSOR()
|
|
||||||
ON_WM_RBUTTONUP()
|
|
||||||
ON_WM_CTLCOLOR()
|
|
||||||
ON_WM_RBUTTONDOWN()
|
|
||||||
END_MESSAGE_MAP()
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CCatchScreenDlg message handlers
|
|
||||||
|
|
||||||
BOOL CCatchScreenDlg::OnInitDialog()
|
|
||||||
{
|
|
||||||
CDialog::OnInitDialog();
|
|
||||||
//把对化框设置成全屏顶层窗口
|
|
||||||
SetWindowPos(&wndTopMost, 0, 0, m_xScreen, m_yScreen, SWP_SHOWWINDOW);
|
|
||||||
|
|
||||||
//移动操作提示窗口
|
|
||||||
CRect rect;
|
|
||||||
m_tipEdit.GetWindowRect(&rect);
|
|
||||||
m_tipEdit.MoveWindow(10, 10, rect.Width(), rect.Height());
|
|
||||||
|
|
||||||
|
|
||||||
m_toolBar.CreateToolBar(m_hWnd);
|
|
||||||
m_toolBar.RemoveChildStyle();
|
|
||||||
::MoveWindow(m_toolBar.GetHWND(),300,300,230,30,FALSE);
|
|
||||||
|
|
||||||
|
|
||||||
UpdateTipString();
|
|
||||||
SetEidtWndText();
|
|
||||||
|
|
||||||
((CScreenshotApp *)AfxGetApp())->m_hwndDlg = AfxGetMainWnd()->GetSafeHwnd();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnPaint()
|
|
||||||
{
|
|
||||||
// 如果窗口是最小化状态
|
|
||||||
if (IsIconic())
|
|
||||||
{
|
|
||||||
CPaintDC dc(this);
|
|
||||||
|
|
||||||
SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);
|
|
||||||
|
|
||||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
||||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
||||||
CRect rect;
|
|
||||||
GetClientRect(&rect);
|
|
||||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
||||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
||||||
|
|
||||||
}
|
|
||||||
else // 如果窗口正常显示
|
|
||||||
{
|
|
||||||
CPaintDC dc(this);
|
|
||||||
|
|
||||||
CDC dcCompatible;
|
|
||||||
|
|
||||||
dcCompatible.CreateCompatibleDC(&dc);
|
|
||||||
RECT rect;
|
|
||||||
::GetClientRect(m_hWnd, &rect);
|
|
||||||
HBITMAP hBitmap = ::CreateCompatibleBitmap(dc.m_hDC,rect.right-rect.left,rect.bottom-rect.top);
|
|
||||||
::SelectObject(dcCompatible.m_hDC,hBitmap);
|
|
||||||
|
|
||||||
HBRUSH s_hBitmapBrush = CreatePatternBrush(m_hBitmap);
|
|
||||||
::FillRect(dcCompatible.m_hDC,&rect,s_hBitmapBrush);
|
|
||||||
|
|
||||||
//显示截取矩形大小信息
|
|
||||||
if (m_bNeedShowMsg && m_bFirstDraw)
|
|
||||||
{
|
|
||||||
CRect rect = m_rectTracker.m_rect;
|
|
||||||
DrawMessage(rect, &dcCompatible);
|
|
||||||
}
|
|
||||||
|
|
||||||
//画出像皮筋矩形
|
|
||||||
if (m_bFirstDraw)
|
|
||||||
{
|
|
||||||
m_rectTracker.Draw(&dcCompatible);
|
|
||||||
}
|
|
||||||
Gdiplus::Graphics graphics(dcCompatible);
|
|
||||||
|
|
||||||
HRGN hgn1 = CreateRectRgn(m_rectTracker.m_rect.left,m_rectTracker.m_rect.top,
|
|
||||||
m_rectTracker.m_rect.right,m_rectTracker.m_rect.bottom);
|
|
||||||
Region region1(hgn1);
|
|
||||||
|
|
||||||
HRGN hgn2 = CreateRectRgn(rect.left,rect.top,
|
|
||||||
rect.right,rect.bottom);
|
|
||||||
Region region2(hgn2);
|
|
||||||
|
|
||||||
region2.Exclude(®ion1);
|
|
||||||
|
|
||||||
SolidBrush solidBrush(Color(100, 128, 128, 128));
|
|
||||||
graphics.FillRegion(&solidBrush,®ion2);
|
|
||||||
|
|
||||||
DeleteObject(hgn1);
|
|
||||||
DeleteObject(hgn2);
|
|
||||||
|
|
||||||
dc.BitBlt(0,0,rect.right, rect.bottom,&dcCompatible,0,0,SRCCOPY);
|
|
||||||
DeleteObject(hBitmap);
|
|
||||||
DeleteObject(s_hBitmapBrush);
|
|
||||||
|
|
||||||
//CDialog::OnPaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnCancel()
|
|
||||||
{
|
|
||||||
if (m_bFirstDraw)
|
|
||||||
{
|
|
||||||
//取消已画矩形变量
|
|
||||||
m_bFirstDraw = FALSE;
|
|
||||||
m_bDraw = FALSE;
|
|
||||||
m_rectTracker.m_rect.SetRect(-1, -1, -1, -1);
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CDialog::OnCancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnMouseMove(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
if(m_bLBtnDown)
|
|
||||||
m_toolBar.HideToolBar();
|
|
||||||
else
|
|
||||||
m_toolBar.ShowToolBar();
|
|
||||||
if (m_bDraw)
|
|
||||||
{
|
|
||||||
//动态调整矩形大小,并刷新画出
|
|
||||||
m_rectTracker.m_rect.SetRect(m_startPt.x + 4, m_startPt.y + 4, point.x, point.y);
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
//弥补调整大小和位置时,接收不到MouseMove消息
|
|
||||||
CRect rect;
|
|
||||||
m_tipEdit.GetWindowRect(&rect);
|
|
||||||
if (rect.PtInRect(point))
|
|
||||||
m_tipEdit.SendMessage(WM_MOUSEMOVE);
|
|
||||||
|
|
||||||
UpdateMousePointRGBString();
|
|
||||||
SetEidtWndText();
|
|
||||||
|
|
||||||
CDialog::OnMouseMove(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnLButtonDown(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
m_bLBtnDown = TRUE;
|
|
||||||
int nHitTest;
|
|
||||||
nHitTest = m_rectTracker.HitTest(point);
|
|
||||||
//判断击中位置
|
|
||||||
if (nHitTest < 0)
|
|
||||||
{
|
|
||||||
if (!m_bFirstDraw)
|
|
||||||
{
|
|
||||||
//第一次画矩形
|
|
||||||
m_startPt = point;
|
|
||||||
m_bDraw = TRUE;
|
|
||||||
m_bFirstDraw = TRUE;
|
|
||||||
//设置当鼠标按下时最小的矩形大小
|
|
||||||
m_rectTracker.m_rect.SetRect(point.x, point.y, point.x + 4, point.y + 4);
|
|
||||||
|
|
||||||
//保证当鼠标当下时立刻显示信息
|
|
||||||
if (m_bFirstDraw)
|
|
||||||
m_bNeedShowMsg = TRUE;
|
|
||||||
UpdateTipString();
|
|
||||||
SetEidtWndText();
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//保证当鼠标当下时立刻显示信息
|
|
||||||
m_bNeedShowMsg = TRUE;
|
|
||||||
if (m_bFirstDraw)
|
|
||||||
{
|
|
||||||
//调束大小时,Track会自动调整矩形大小,在些期间,消息归CRectTracker内部处理
|
|
||||||
m_rectTracker.Track(this, point, TRUE);
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CDialog::OnLButtonDown(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnLButtonUp(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
m_bLBtnDown = FALSE;
|
|
||||||
m_bNeedShowMsg = FALSE;
|
|
||||||
m_bDraw = FALSE;
|
|
||||||
UpdateTipString();
|
|
||||||
SetEidtWndText();
|
|
||||||
m_toolBar.SetShowPlace(m_rectTracker.m_rect.right,m_rectTracker.m_rect.bottom);
|
|
||||||
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
CDialog::OnLButtonUp(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
int nHitTest;
|
|
||||||
nHitTest = m_rectTracker.HitTest(point);
|
|
||||||
|
|
||||||
//如果在是矩形内部双击
|
|
||||||
if (nHitTest == 8)
|
|
||||||
{
|
|
||||||
//保存位图到粘贴板中,bSave 为TRUE,
|
|
||||||
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDialog::OnLButtonDblClk(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnRButtonDown(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
m_toolBar.HideToolBar();
|
|
||||||
//InvalidateRgnWindow();
|
|
||||||
CDialog::OnRButtonDown(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::OnRButtonUp(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
m_bLBtnDown = FALSE;
|
|
||||||
if (m_bFirstDraw)
|
|
||||||
{
|
|
||||||
//如果已经截取矩则清除截取矩形
|
|
||||||
m_bFirstDraw = FALSE;
|
|
||||||
//清除矩形大小
|
|
||||||
m_rectTracker.m_rect.SetRect(-1, -1, -1, -1);
|
|
||||||
UpdateTipString();
|
|
||||||
SetEidtWndText();
|
|
||||||
InvalidateRgnWindow();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//关闭程序
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDialog::OnRButtonUp(nFlags, point);
|
|
||||||
}
|
|
||||||
|
|
||||||
HBRUSH CCatchScreenDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
|
|
||||||
{
|
|
||||||
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
|
|
||||||
|
|
||||||
//设置操作提示窗口文本颜色
|
|
||||||
if (pWnd->GetDlgCtrlID() == IDC_EDIT1)
|
|
||||||
{
|
|
||||||
pDC->SetTextColor(RGB(247,76,128));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hbr;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CCatchScreenDlg::OnEraseBkgnd(CDC* pDC)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
//用整个桌面填充全屏对话框背景
|
|
||||||
BITMAP bmp;
|
|
||||||
m_pBitmap->GetBitmap(&bmp);
|
|
||||||
|
|
||||||
CDC dcCompatible;
|
|
||||||
dcCompatible.CreateCompatibleDC(pDC);
|
|
||||||
|
|
||||||
dcCompatible.SelectObject(m_pBitmap);
|
|
||||||
|
|
||||||
CRect rect;
|
|
||||||
GetClientRect(&rect);
|
|
||||||
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CCatchScreenDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
|
|
||||||
{
|
|
||||||
//设置改变截取矩形大小时光标
|
|
||||||
if (pWnd == this &&m_rectTracker.SetCursor(this, nHitTest)
|
|
||||||
&& !m_bDraw &&m_bFirstDraw) //此处判断保截取时当标始中为彩色光标
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//设置彩色光标
|
|
||||||
SetCursor(m_hCursor);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 拷贝屏幕, 这段源码源自CSDN
|
|
||||||
// lpRect 代表选定区域
|
|
||||||
HBITMAP CCatchScreenDlg::CopyScreenToBitmap(LPRECT lpRect, BOOL bSave)
|
|
||||||
|
|
||||||
{
|
|
||||||
HDC hScrDC, hMemDC;
|
|
||||||
// 屏幕和内存设备描述表
|
|
||||||
HBITMAP hBitmap, hOldBitmap;
|
|
||||||
// 位图句柄
|
|
||||||
int nX, nY, nX2, nY2;
|
|
||||||
// 选定区域坐标
|
|
||||||
int nWidth, nHeight;
|
|
||||||
|
|
||||||
// 确保选定区域不为空矩形
|
|
||||||
if (IsRectEmpty(lpRect))
|
|
||||||
return NULL;
|
|
||||||
//为屏幕创建设备描述表
|
|
||||||
hScrDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
|
|
||||||
|
|
||||||
//为屏幕设备描述表创建兼容的内存设备描述表
|
|
||||||
hMemDC = CreateCompatibleDC(hScrDC);
|
|
||||||
// 获得选定区域坐标
|
|
||||||
nX = lpRect->left;
|
|
||||||
nY = lpRect->top;
|
|
||||||
nX2 = lpRect->right;
|
|
||||||
nY2 = lpRect->bottom;
|
|
||||||
|
|
||||||
//确保选定区域是可见的
|
|
||||||
if (nX < 0)
|
|
||||||
nX = 0;
|
|
||||||
if (nY < 0)
|
|
||||||
nY = 0;
|
|
||||||
if (nX2 > m_xScreen)
|
|
||||||
nX2 = m_xScreen;
|
|
||||||
if (nY2 > m_yScreen)
|
|
||||||
nY2 = m_yScreen;
|
|
||||||
nWidth = nX2 - nX;
|
|
||||||
nHeight = nY2 - nY;
|
|
||||||
// 创建一个与屏幕设备描述表兼容的位图
|
|
||||||
hBitmap = CreateCompatibleBitmap
|
|
||||||
(hScrDC, nWidth, nHeight);
|
|
||||||
// 把新位图选到内存设备描述表中
|
|
||||||
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
|
|
||||||
// 把屏幕设备描述表拷贝到内存设备描述表中
|
|
||||||
if (bSave)
|
|
||||||
{
|
|
||||||
//创建兼容DC,当bSave为中时把开始保存的全屏位图,按截取矩形大小保存
|
|
||||||
CDC dcCompatible;
|
|
||||||
dcCompatible.CreateCompatibleDC(CDC::FromHandle(hMemDC));
|
|
||||||
dcCompatible.SelectObject(m_pBitmap);
|
|
||||||
|
|
||||||
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
|
|
||||||
dcCompatible, nX, nY, SRCCOPY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
|
|
||||||
hScrDC, nX, nY, SRCCOPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
|
|
||||||
//得到屏幕位图的句柄
|
|
||||||
//清除
|
|
||||||
DeleteDC(hScrDC);
|
|
||||||
DeleteDC(hMemDC);
|
|
||||||
|
|
||||||
if (bSave)
|
|
||||||
{
|
|
||||||
if (OpenClipboard())
|
|
||||||
{
|
|
||||||
//清空剪贴板
|
|
||||||
EmptyClipboard();
|
|
||||||
//把屏幕内容粘贴到剪贴板上,
|
|
||||||
//hBitmap 为刚才的屏幕位图句柄
|
|
||||||
SetClipboardData(CF_BITMAP, hBitmap);
|
|
||||||
//关闭剪贴板
|
|
||||||
CloseClipboard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 返回位图句柄
|
|
||||||
return hBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示操作提示信息
|
|
||||||
void CCatchScreenDlg::UpdateTipString()
|
|
||||||
{
|
|
||||||
CString strTemp;
|
|
||||||
if (!m_bDraw && !m_bFirstDraw)
|
|
||||||
{
|
|
||||||
strTemp = _T("\r\n\r\n·按下鼠标左键不放选择截取\r\n\r\n·ESC键、鼠标右键退出");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (m_bDraw && m_bFirstDraw)
|
|
||||||
{
|
|
||||||
strTemp = _T("\r\n\r\n·松开鼠标左键确定截取范围\r\n\r\n·ESC键退出");
|
|
||||||
}
|
|
||||||
else if (!m_bDraw && m_bFirstDraw)
|
|
||||||
{
|
|
||||||
CString sudami(_T("\r\n\r\n·矩形内双击鼠标左键保存\r\n\r\n·点击鼠标右键重新选择"));
|
|
||||||
strTemp = _T("\r\n\r\n·鼠标在矩形边缘调整大小");
|
|
||||||
|
|
||||||
strTemp += sudami;
|
|
||||||
}
|
|
||||||
m_strEditTip = strTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示截取矩形信息
|
|
||||||
void CCatchScreenDlg::DrawMessage(CRect &inRect, CDC * pDC)
|
|
||||||
{
|
|
||||||
//截取矩形大小信息离鼠标间隔
|
|
||||||
const int space = 3;
|
|
||||||
|
|
||||||
//设置字体颜色大小
|
|
||||||
CPoint pt;
|
|
||||||
CPen pen(PS_SOLID, 1, RGB(47, 79, 79));
|
|
||||||
CPen *pOldPen;
|
|
||||||
pOldPen = pDC->SelectObject(&pen);
|
|
||||||
|
|
||||||
//pDC->SetTextColor(RGB(147,147,147));
|
|
||||||
CFont font;
|
|
||||||
CFont * pOldFont;
|
|
||||||
font.CreatePointFont(90, _T("宋体"));
|
|
||||||
pOldFont = pDC->SelectObject(&font);
|
|
||||||
|
|
||||||
//得到字体宽度和高度
|
|
||||||
GetCursorPos(&pt);
|
|
||||||
int OldBkMode;
|
|
||||||
OldBkMode = pDC->SetBkMode(TRANSPARENT);
|
|
||||||
|
|
||||||
TEXTMETRIC tm;
|
|
||||||
int charHeight;
|
|
||||||
CSize size;
|
|
||||||
int lineLength;
|
|
||||||
pDC->GetTextMetrics(&tm);
|
|
||||||
charHeight = tm.tmHeight + tm.tmExternalLeading;
|
|
||||||
size = pDC->GetTextExtent(_T("顶点位置 "), _tcslen(_T("顶点位置 ")));
|
|
||||||
lineLength = size.cx;
|
|
||||||
|
|
||||||
//初始化矩形, 以保证写下六行文字
|
|
||||||
CRect rect(pt.x + space, pt.y - charHeight * 6 - space, pt.x + lineLength + space, pt.y - space);
|
|
||||||
|
|
||||||
//创建临时矩形
|
|
||||||
CRect rectTemp;
|
|
||||||
//当矩形到达桌面边缘时调整方向和大小
|
|
||||||
if ((pt.x + rect.Width()) >= m_xScreen)
|
|
||||||
{
|
|
||||||
//桌面上方显示不下矩形
|
|
||||||
rectTemp = rect;
|
|
||||||
rectTemp.left = rect.left - rect.Width() - space * 2;
|
|
||||||
rectTemp.right = rect.right - rect.Width() - space * 2;;
|
|
||||||
rect = rectTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((pt.y - rect.Height()) <= 0)
|
|
||||||
{
|
|
||||||
//桌面右方显示不下矩形
|
|
||||||
rectTemp = rect;
|
|
||||||
rectTemp.top = rect.top + rect.Height() + space * 2;;
|
|
||||||
rectTemp.bottom = rect.bottom + rect.Height() + space * 2;;
|
|
||||||
rect = rectTemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//创建空画刷画矩形
|
|
||||||
CBrush * pOldBrush;
|
|
||||||
pOldBrush = pDC->SelectObject(CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)));
|
|
||||||
|
|
||||||
pDC->Rectangle(rect);
|
|
||||||
rect.top += 2;
|
|
||||||
//在矩形中显示文字
|
|
||||||
CRect outRect(rect.left, rect.top, rect.left + lineLength, rect.top + charHeight);
|
|
||||||
CString string(_T("顶点位置"));
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
outRect.SetRect(rect.left, rect.top + charHeight, rect.left + lineLength, charHeight + rect.top + charHeight);
|
|
||||||
string.Format(_T("(%d,%d)"), inRect.left, inRect.top);
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
|
|
||||||
outRect.SetRect(rect.left, rect.top + charHeight * 2, rect.left + lineLength, charHeight + rect.top + charHeight * 2);
|
|
||||||
string = _T("矩形大小");
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
outRect.SetRect(rect.left, rect.top + charHeight * 3, rect.left + lineLength, charHeight + rect.top + charHeight * 3);
|
|
||||||
string.Format(_T("(%d,%d)"), inRect.Width(), inRect.Height());
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
outRect.SetRect(rect.left, rect.top + charHeight * 4, rect.left + lineLength, charHeight + rect.top + charHeight * 4);
|
|
||||||
string = _T("光标坐标");
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
outRect.SetRect(rect.left, rect.top + charHeight * 5, rect.left + lineLength, charHeight + rect.top + charHeight * 5);
|
|
||||||
string.Format(_T("(%d,%d)"), pt.x, pt.y);
|
|
||||||
pDC->DrawText(string, outRect, DT_CENTER);
|
|
||||||
|
|
||||||
pDC->SetBkMode(OldBkMode);
|
|
||||||
pDC->SelectObject(pOldFont);
|
|
||||||
pDC->SelectObject(pOldBrush);
|
|
||||||
pDC->SelectObject(pOldPen);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 刷新局部窗口
|
|
||||||
void CCatchScreenDlg::InvalidateRgnWindow()
|
|
||||||
{
|
|
||||||
//获取当全屏对话框窗口大小
|
|
||||||
CRect rect1;
|
|
||||||
GetWindowRect(rect1);
|
|
||||||
|
|
||||||
//获取编辑框窗口大小
|
|
||||||
CRect rect2;
|
|
||||||
m_tipEdit.GetWindowRect(rect2);
|
|
||||||
|
|
||||||
CRgn rgn1, rgn2;
|
|
||||||
rgn1.CreateRectRgnIndirect(rect1);
|
|
||||||
rgn2.CreateRectRgnIndirect(rect2);
|
|
||||||
|
|
||||||
//获取更新区域,就是除了编辑框窗口不更新
|
|
||||||
//m_rgn.CombineRgn(&rgn1, &rgn2, RGN_DIFF);
|
|
||||||
|
|
||||||
// 添加ToolBar不刷新
|
|
||||||
CRect rect3;
|
|
||||||
::GetWindowRect(m_toolBar.GetHWND(),&rect3);
|
|
||||||
CRgn rgn3;
|
|
||||||
rgn3.CreateRectRgnIndirect(rect3);
|
|
||||||
|
|
||||||
CRgn rgnTemp;
|
|
||||||
rgnTemp.CreateRectRgn(0, 0, 50, 50);
|
|
||||||
rgnTemp.CombineRgn(&rgn1, &rgn2, RGN_DIFF);
|
|
||||||
m_rgn.CombineRgn(&rgnTemp, &rgn3, RGN_DIFF);
|
|
||||||
|
|
||||||
InvalidateRgn(&m_rgn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::UpdateMousePointRGBString()
|
|
||||||
{
|
|
||||||
static CString strOld("");
|
|
||||||
|
|
||||||
CPoint pt;
|
|
||||||
GetCursorPos(&pt);
|
|
||||||
|
|
||||||
COLORREF color;
|
|
||||||
CClientDC dc(this);
|
|
||||||
color = dc.GetPixel(pt);
|
|
||||||
BYTE rValue, gValue, bValue;
|
|
||||||
rValue = GetRValue(color);
|
|
||||||
gValue = GetGValue(color);
|
|
||||||
bValue = GetGValue(color);
|
|
||||||
|
|
||||||
//按格式排放字符串
|
|
||||||
CString string;
|
|
||||||
string.Format(_T("\r\n\r\n·当前像素RGB(%d,%d,%d)"), rValue, gValue, bValue);
|
|
||||||
|
|
||||||
//如果当前颜色没变则不刷新RGB值,以免窗口有更多闪烁
|
|
||||||
if (strOld != string)
|
|
||||||
{
|
|
||||||
m_strRgb = string;
|
|
||||||
}
|
|
||||||
strOld = string;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCatchScreenDlg::SetEidtWndText()
|
|
||||||
{
|
|
||||||
m_tipEdit.SetWindowText(this->GetEditText());
|
|
||||||
}
|
|
||||||
|
|
||||||
CString CCatchScreenDlg::GetEditText()
|
|
||||||
{
|
|
||||||
CString str;
|
|
||||||
str.Append(m_strRgb);
|
|
||||||
str.Append(m_strEditTip);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CCatchScreenDlg::OnCommand(WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
bool bHandle = true;
|
|
||||||
HWND hWnd = m_toolBar.GetHWND();
|
|
||||||
if(lParam == (LPARAM)m_toolBar.GetHWND())
|
|
||||||
{
|
|
||||||
int wmId = LOWORD(wParam);
|
|
||||||
switch(wmId)
|
|
||||||
{
|
|
||||||
case MyToolBar_ID:
|
|
||||||
AfxMessageBox(_T("矩形"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID+1:
|
|
||||||
AfxMessageBox(_T("圆形"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +2:
|
|
||||||
AfxMessageBox(_T("画笔"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +3:
|
|
||||||
AfxMessageBox(_T("马赛克"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +4:
|
|
||||||
AfxMessageBox(_T("文字"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +5:
|
|
||||||
AfxMessageBox(_T("撤销"));
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +6:
|
|
||||||
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +7:
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
case MyToolBar_ID +8:
|
|
||||||
CopyScreenToBitmap(m_rectTracker.m_rect, TRUE);
|
|
||||||
PostQuitMessage(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bHandle = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
::SetFocus(hWnd);
|
|
||||||
}
|
|
||||||
if (bHandle == false)
|
|
||||||
{
|
|
||||||
return CDialog::OnCommand(wParam,lParam);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////// END OF FILE ///////////////////////////////////////
|
|
@ -1,90 +0,0 @@
|
|||||||
#if !defined(AFX_CATCHSCREENDLG_H__536FDBC8_7DB2_4BEF_8943_70DBE8AD845F__INCLUDED_)
|
|
||||||
#define AFX_CATCHSCREENDLG_H__536FDBC8_7DB2_4BEF_8943_70DBE8AD845F__INCLUDED_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
#include "Resource.h"
|
|
||||||
#include "MyEdit.h"
|
|
||||||
|
|
||||||
#ifndef MYTRACKER_
|
|
||||||
#include "MyTracker.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "MyToolBar.h"
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
class CCatchScreenDlg : public CDialog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
CCatchScreenDlg(CWnd* pParent = NULL);
|
|
||||||
|
|
||||||
enum { IDD = IDD_DIALOGFORIMG };
|
|
||||||
CMyEdit m_tipEdit;
|
|
||||||
CMyToolBar m_toolBar;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
int m_xScreen;
|
|
||||||
int m_yScreen;
|
|
||||||
|
|
||||||
|
|
||||||
BOOL m_bLBtnDown;
|
|
||||||
|
|
||||||
BOOL m_bNeedShowMsg; // 显示截取矩形大小信息
|
|
||||||
BOOL m_bDraw; // 是否为截取状态
|
|
||||||
BOOL m_bFirstDraw; // 是否为首次截取
|
|
||||||
BOOL m_bQuit; // 是否为退出
|
|
||||||
CPoint m_startPt; // 截取矩形左上角位置
|
|
||||||
|
|
||||||
CMyTracker m_rectTracker; // 像皮筋类
|
|
||||||
CBrush m_brush;
|
|
||||||
HCURSOR m_hCursor; // 光标
|
|
||||||
CBitmap* m_pBitmap; // Edit关联控件的背景位图
|
|
||||||
HBITMAP m_hBitmap;
|
|
||||||
|
|
||||||
CRgn m_rgn; // 背景擦除区域
|
|
||||||
|
|
||||||
public:
|
|
||||||
HBITMAP CopyScreenToBitmap(LPRECT lpRect,BOOL bSave=FALSE); /* 拷贝桌面到位图 */
|
|
||||||
void UpdateTipString(); //显示操作提示信息
|
|
||||||
void DrawMessage(CRect &inRect,CDC * pDC); //显示截取矩形信息
|
|
||||||
void InvalidateRgnWindow(); //重画窗口
|
|
||||||
void UpdateMousePointRGBString();
|
|
||||||
|
|
||||||
CString m_strRgb;
|
|
||||||
CString m_strEditTip;
|
|
||||||
|
|
||||||
void SetEidtWndText();
|
|
||||||
CString GetEditText();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void DoDataExchange(CDataExchange* pDX);
|
|
||||||
virtual BOOL OnInitDialog();
|
|
||||||
virtual void OnCancel();
|
|
||||||
|
|
||||||
afx_msg void OnPaint();
|
|
||||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
|
||||||
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
|
|
||||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
|
||||||
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
|
|
||||||
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
|
|
||||||
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
|
|
||||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
|
||||||
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
|
|
||||||
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
|
|
||||||
|
|
||||||
|
|
||||||
DECLARE_MESSAGE_MAP()
|
|
||||||
|
|
||||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,120 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* FileName : MyEdit.CPP
|
|
||||||
* Author : Unknown
|
|
||||||
* Mender : sudami
|
|
||||||
* Time : 2007/09/09
|
|
||||||
*
|
|
||||||
* Comment :
|
|
||||||
*--------------------------------------------------------
|
|
||||||
* 截图程序中的一个控件封装类.
|
|
||||||
* 将控件和该类关联后,可以显示出当前截图的一些提示信息
|
|
||||||
*--------------------------------------------------------
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "MyEdit.h"
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 构造函数、析构函数
|
|
||||||
//
|
|
||||||
CMyEdit::CMyEdit()
|
|
||||||
{
|
|
||||||
m_bMove=TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMyEdit::~CMyEdit()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CMyEdit, CEdit)
|
|
||||||
/* 2个小消息 */
|
|
||||||
ON_WM_CREATE()
|
|
||||||
ON_WM_PAINT()
|
|
||||||
ON_WM_SETFOCUS()
|
|
||||||
/* 3个大消息 */
|
|
||||||
ON_WM_MOUSEMOVE()
|
|
||||||
ON_WM_ERASEBKGND()
|
|
||||||
END_MESSAGE_MAP()
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
int CMyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
|
||||||
{
|
|
||||||
if (CEdit::OnCreate(lpCreateStruct) == -1)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CMyEdit::OnPaint()
|
|
||||||
{
|
|
||||||
CPaintDC dc(this);
|
|
||||||
|
|
||||||
CDC dcCompatible;
|
|
||||||
dcCompatible.CreateCompatibleDC(&dc);
|
|
||||||
|
|
||||||
dcCompatible.SetBkMode(TRANSPARENT);
|
|
||||||
CBitmap bitmap;
|
|
||||||
bitmap.LoadBitmap(IDB_BITMAP_BK);
|
|
||||||
dcCompatible.SelectObject(&bitmap);
|
|
||||||
|
|
||||||
RECT rt = {5,5,0,0};
|
|
||||||
RECT rtClient = {0};
|
|
||||||
GetClientRect(&rtClient);
|
|
||||||
rt.right = rtClient.right;
|
|
||||||
rt.bottom = rtClient.bottom;
|
|
||||||
|
|
||||||
CString str;
|
|
||||||
GetWindowText(str);
|
|
||||||
CFont font;
|
|
||||||
CFont * pOldFont;
|
|
||||||
font.CreatePointFont(90, _T("宋体"));
|
|
||||||
pOldFont = dcCompatible.SelectObject(&font);
|
|
||||||
dcCompatible.DrawText(str,&rt,DT_LEFT);
|
|
||||||
dcCompatible.SelectObject(pOldFont);
|
|
||||||
|
|
||||||
CRect rect;
|
|
||||||
GetClientRect(&rect);
|
|
||||||
dc.BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// <响应 WM_MOUSEMOVE 消息>
|
|
||||||
// 和QQ的截图差不多的效果,只要鼠标挪到该控件区域,该区域就变换位置
|
|
||||||
//
|
|
||||||
void CMyEdit::OnMouseMove(UINT nFlags, CPoint point)
|
|
||||||
{
|
|
||||||
CEdit::OnMouseMove(nFlags, point);
|
|
||||||
CRect rect;
|
|
||||||
GetWindowRect(&rect);
|
|
||||||
int xScreen = GetSystemMetrics(SM_CXSCREEN);
|
|
||||||
if(m_bMove)
|
|
||||||
{
|
|
||||||
//移动到左上角
|
|
||||||
MoveWindow(10,10,rect.Width(),rect.Height());
|
|
||||||
m_bMove=FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//移动到右上角
|
|
||||||
MoveWindow(xScreen-180,10,rect.Width(),rect.Height());
|
|
||||||
m_bMove=TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
void CMyEdit::OnSetFocus(CWnd* pOldWnd)
|
|
||||||
{
|
|
||||||
CEdit::OnSetFocus(pOldWnd);
|
|
||||||
|
|
||||||
// 隐藏光标提示符
|
|
||||||
this->HideCaret();
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyEdit::OnEraseBkgnd(CDC* pDC)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* FileName : MyEdit.h
|
|
||||||
* Author : Unknown
|
|
||||||
* Mender : sudami
|
|
||||||
* Time : 2007/09/09
|
|
||||||
*
|
|
||||||
* Comment :
|
|
||||||
*--------------------------------------------------------
|
|
||||||
* 截图程序中的一个控件封装类.
|
|
||||||
* 将控件和该类关联后,可以显示出当前截图的一些提示信息
|
|
||||||
*--------------------------------------------------------
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#if !defined(AFX_MYEDIT_H__A34EEA6D_E8FC_4D15_B03C_BAA42FDF6FCB__INCLUDED_)
|
|
||||||
#define AFX_MYEDIT_H__A34EEA6D_E8FC_4D15_B03C_BAA42FDF6FCB__INCLUDED_
|
|
||||||
|
|
||||||
#if _MSC_VER > 1000
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <afxwin.h>
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class CMyEdit : public CEdit
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CMyEdit();
|
|
||||||
virtual ~CMyEdit();
|
|
||||||
|
|
||||||
BOOL m_bMove; // 类似"单刀双掷开关"
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
|
|
||||||
afx_msg void OnSetFocus(CWnd* pOldWnd);
|
|
||||||
|
|
||||||
afx_msg void OnPaint();
|
|
||||||
|
|
||||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
|
||||||
|
|
||||||
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
|
|
||||||
|
|
||||||
DECLARE_MESSAGE_MAP()
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,148 +0,0 @@
|
|||||||
#include "StdAfx.h"
|
|
||||||
#include "MyToolBar.h"
|
|
||||||
#include <GdiPlus.h>
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BOOL ImageFromIDResource(UINT nID, LPCTSTR sTR, Gdiplus::Bitmap * & pImg)
|
|
||||||
{
|
|
||||||
HINSTANCE hInst = AfxGetResourceHandle();
|
|
||||||
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
|
|
||||||
if (!hRsrc)
|
|
||||||
return FALSE;
|
|
||||||
// load resource into memory
|
|
||||||
DWORD len = SizeofResource(hInst, hRsrc);
|
|
||||||
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
|
|
||||||
if (!lpRsrc)
|
|
||||||
return FALSE;
|
|
||||||
// Allocate global memory on which to create stream
|
|
||||||
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
|
|
||||||
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
|
|
||||||
memcpy(pmem,lpRsrc,len);
|
|
||||||
IStream* pstm;
|
|
||||||
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
|
|
||||||
// load from stream
|
|
||||||
pImg=Gdiplus::Bitmap::FromStream(pstm);
|
|
||||||
// free/release stuff
|
|
||||||
GlobalUnlock(m_hMem);
|
|
||||||
pstm->Release();
|
|
||||||
FreeResource(lpRsrc);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMyToolBar::CMyToolBar()
|
|
||||||
{
|
|
||||||
m_hImageList = NULL;
|
|
||||||
m_hWnd_toolbar = 0;
|
|
||||||
m_hWndParent = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMyToolBar::~CMyToolBar(void)
|
|
||||||
{
|
|
||||||
ImageList_Destroy(m_hImageList);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyToolBar::CreateToolBar(HWND hWndParent)
|
|
||||||
{
|
|
||||||
if (m_hImageList)
|
|
||||||
return FALSE;
|
|
||||||
m_hWndParent = hWndParent;
|
|
||||||
|
|
||||||
m_hImageList= ImageList_Create(18,18,ILC_COLOR32,1,1);
|
|
||||||
Gdiplus::Bitmap * pImage = NULL;
|
|
||||||
for(int i=0;i< 9;i++)
|
|
||||||
{
|
|
||||||
ImageFromIDResource(IDB_RECTANGLE + i,_T("PNG"),pImage);
|
|
||||||
HBITMAP pHbitmap=0;;
|
|
||||||
if(pImage)
|
|
||||||
{
|
|
||||||
pImage->GetHBITMAP(Gdiplus::Color(0xff,0xff,0xff,0xff),&pHbitmap);
|
|
||||||
ImageList_Add(m_hImageList,pHbitmap,NULL);
|
|
||||||
delete pImage;
|
|
||||||
pImage = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hWnd_toolbar = ::CreateWindowEx(0,TOOLBARCLASSNAME,0,WS_CHILD | WS_VISIBLE|WS_BORDER ,
|
|
||||||
0,0,0,0,hWndParent,NULL,GetModuleHandle(NULL),NULL);
|
|
||||||
|
|
||||||
if (m_hWnd_toolbar == NULL)
|
|
||||||
return FALSE;
|
|
||||||
::SendMessage(m_hWnd_toolbar,TB_SETIMAGELIST, 0, (LPARAM) m_hImageList);
|
|
||||||
::SendMessage(m_hWnd_toolbar,TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
|
|
||||||
|
|
||||||
|
|
||||||
::SendMessage(m_hWnd_toolbar,
|
|
||||||
(UINT) TB_SETBITMAPSIZE,(WPARAM) 0,//not used, must be zero
|
|
||||||
(LPARAM) MAKELONG (18, 18)// = (LPARAM) MAKELONG (dxBitmap, dyBitmap)
|
|
||||||
);
|
|
||||||
|
|
||||||
//TCHAR tooltips[16][30]={_T("AAAA"),_T("BBBB"),_T("CCCC"),_T("DDDD")};
|
|
||||||
for(int i = 0; i < 9; i++)
|
|
||||||
{
|
|
||||||
TBBUTTON tbbutton;
|
|
||||||
// 换行
|
|
||||||
int wrapnow = 0;
|
|
||||||
//if (i % 2 == 1)
|
|
||||||
// wrapnow = TBSTATE_WRAP;
|
|
||||||
|
|
||||||
ZeroMemory(&tbbutton, sizeof(TBBUTTON));
|
|
||||||
//tbbutton.iString = (INT_PTR) tooltips[i];
|
|
||||||
tbbutton.fsStyle = TBSTYLE_CHECKGROUP; // 单选属性
|
|
||||||
tbbutton.fsState = TBSTATE_ENABLED | wrapnow;
|
|
||||||
tbbutton.idCommand = MyToolBar_ID + i; // 定义控件的id
|
|
||||||
tbbutton.iBitmap = i;
|
|
||||||
|
|
||||||
::SendMessage(m_hWnd_toolbar,TB_ADDBUTTONS, 1, (LPARAM) &tbbutton);
|
|
||||||
}
|
|
||||||
::SendMessage(m_hWnd_toolbar, TB_AUTOSIZE, 0, 0);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND CMyToolBar::GetHWND()
|
|
||||||
{
|
|
||||||
return m_hWnd_toolbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::AddChildStyle()
|
|
||||||
{
|
|
||||||
DWORD dwStyle = GetWindowLong(m_hWnd_toolbar, GWL_STYLE);
|
|
||||||
dwStyle &= WS_CHILD;
|
|
||||||
SetWindowLong(m_hWnd_toolbar,GWL_STYLE,dwStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::RemoveChildStyle()
|
|
||||||
{
|
|
||||||
|
|
||||||
DWORD dwStyle = GetWindowLong(m_hWnd_toolbar, GWL_STYLE);
|
|
||||||
dwStyle &= ~WS_CHILD;
|
|
||||||
SetWindowLong(m_hWnd_toolbar,GWL_STYLE,dwStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::ShowToolBar()
|
|
||||||
{
|
|
||||||
::ShowWindow(m_hWnd_toolbar,SW_SHOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::HideToolBar()
|
|
||||||
{
|
|
||||||
::ShowWindow(m_hWnd_toolbar,SW_HIDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::SetAtCurMousePlase()
|
|
||||||
{
|
|
||||||
RECT rtWin = {0};
|
|
||||||
::GetWindowRect(m_hWnd_toolbar,&rtWin);
|
|
||||||
POINT pt = {0};
|
|
||||||
::GetCursorPos(&pt);
|
|
||||||
this->SetShowPlace(pt.x,pt.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyToolBar::SetShowPlace(int nCurPointX,int nCurPointY)
|
|
||||||
{
|
|
||||||
|
|
||||||
RECT rtWin = {0};
|
|
||||||
::GetWindowRect(m_hWnd_toolbar,&rtWin);
|
|
||||||
::SetWindowPos(m_hWnd_toolbar,HWND_TOP,nCurPointX - (rtWin.right-rtWin.left),nCurPointY + 2,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#define MyToolBar_ID 600
|
|
||||||
|
|
||||||
class CMyToolBar
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CMyToolBar();
|
|
||||||
~CMyToolBar(void);
|
|
||||||
|
|
||||||
BOOL CreateToolBar(HWND hWndParent);
|
|
||||||
void AddChildStyle();
|
|
||||||
void RemoveChildStyle();
|
|
||||||
void ShowToolBar();
|
|
||||||
void HideToolBar();
|
|
||||||
void SetAtCurMousePlase();
|
|
||||||
void SetShowPlace(int nCurPointX,int nCurPointY);
|
|
||||||
HWND GetHWND();
|
|
||||||
private:
|
|
||||||
HIMAGELIST m_hImageList;
|
|
||||||
HWND m_hWndParent;
|
|
||||||
HWND m_hWnd_toolbar;
|
|
||||||
};
|
|
@ -1,839 +0,0 @@
|
|||||||
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
||||||
// Copyright (C) 1992-1998 Microsoft Corporation
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This source code is only intended as a supplement to the
|
|
||||||
// Microsoft Foundation Classes Reference and related
|
|
||||||
// electronic documentation provided with the library.
|
|
||||||
// See these sources for detailed information regarding the
|
|
||||||
// Microsoft Foundation Classes product.
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "MyTracker.h"
|
|
||||||
#include "Resource.h"
|
|
||||||
#include "CatchScreenDlg.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CMyTracker global state
|
|
||||||
|
|
||||||
// various GDI objects we need to draw
|
|
||||||
AFX_STATIC_DATA HCURSOR _afxCursors[10] = { 0,};
|
|
||||||
AFX_STATIC_DATA HBRUSH _afxHatchBrush = 0;
|
|
||||||
AFX_STATIC_DATA HPEN _afxBlackDottedPen = 0;
|
|
||||||
AFX_STATIC_DATA HPEN _afxBlackSolidPen = 0;
|
|
||||||
AFX_STATIC_DATA int _afxHandleSize = 0;
|
|
||||||
|
|
||||||
void AFX_CDECL AfxTrackerTerm()
|
|
||||||
{
|
|
||||||
AfxDeleteObject((HGDIOBJ*)&_afxHatchBrush);
|
|
||||||
AfxDeleteObject((HGDIOBJ*)&_afxBlackDottedPen);
|
|
||||||
}
|
|
||||||
char _afxTrackerTerm = (char)atexit(&AfxTrackerTerm);
|
|
||||||
|
|
||||||
// the struct below is used to determine the qualities of a particular handle
|
|
||||||
struct AFX_HANDLEINFO
|
|
||||||
{
|
|
||||||
size_t nOffsetX; // offset within RECT for X coordinate
|
|
||||||
size_t nOffsetY; // offset within RECT for Y coordinate
|
|
||||||
int nCenterX; // adjust X by Width()/2 * this number
|
|
||||||
int nCenterY; // adjust Y by Height()/2 * this number
|
|
||||||
int nHandleX; // adjust X by handle size * this number
|
|
||||||
int nHandleY; // adjust Y by handle size * this number
|
|
||||||
int nInvertX; // handle converts to this when X inverted
|
|
||||||
int nInvertY; // handle converts to this when Y inverted
|
|
||||||
};
|
|
||||||
|
|
||||||
// this array describes all 8 handles (clock-wise)
|
|
||||||
AFX_STATIC_DATA const AFX_HANDLEINFO _afxHandleInfo[] =
|
|
||||||
{
|
|
||||||
// corner handles (top-left, top-right, bottom-right, bottom-left
|
|
||||||
{ offsetof(RECT, left), offsetof(RECT, top), 0, 0, 0, 0, 1, 3 },
|
|
||||||
{ offsetof(RECT, right), offsetof(RECT, top), 0, 0, -1, 0, 0, 2 },
|
|
||||||
{ offsetof(RECT, right), offsetof(RECT, bottom), 0, 0, -1, -1, 3, 1 },
|
|
||||||
{ offsetof(RECT, left), offsetof(RECT, bottom), 0, 0, 0, -1, 2, 0 },
|
|
||||||
|
|
||||||
// side handles (top, right, bottom, left)
|
|
||||||
{ offsetof(RECT, left), offsetof(RECT, top), 1, 0, 0, 0, 4, 6 },
|
|
||||||
{ offsetof(RECT, right), offsetof(RECT, top), 0, 1, -1, 0, 7, 5 },
|
|
||||||
{ offsetof(RECT, left), offsetof(RECT, bottom), 1, 0, 0, -1, 6, 4 },
|
|
||||||
{ offsetof(RECT, left), offsetof(RECT, top), 0, 1, 0, 0, 5, 7 }
|
|
||||||
};
|
|
||||||
|
|
||||||
// the struct below gives us information on the layout of a RECT struct and
|
|
||||||
// the relationship between its members
|
|
||||||
struct AFX_RECTINFO
|
|
||||||
{
|
|
||||||
size_t nOffsetAcross; // offset of opposite point (ie. left->right)
|
|
||||||
int nSignAcross; // sign relative to that point (ie. add/subtract)
|
|
||||||
};
|
|
||||||
|
|
||||||
// this array is indexed by the offset of the RECT member / sizeof(int)
|
|
||||||
AFX_STATIC_DATA const AFX_RECTINFO _afxRectInfo[] =
|
|
||||||
{
|
|
||||||
{ offsetof(RECT, right), +1 },
|
|
||||||
{ offsetof(RECT, bottom), +1 },
|
|
||||||
{ offsetof(RECT, left), -1 },
|
|
||||||
{ offsetof(RECT, top), -1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CMyTracker intitialization
|
|
||||||
|
|
||||||
CMyTracker::CMyTracker(LPCRECT lpSrcRect, UINT nStyle)
|
|
||||||
{
|
|
||||||
ASSERT(AfxIsValidAddress(lpSrcRect, sizeof(RECT), FALSE));
|
|
||||||
|
|
||||||
Construct();
|
|
||||||
m_rect.CopyRect(lpSrcRect);
|
|
||||||
m_nStyle = nStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMyTracker::CMyTracker()
|
|
||||||
{
|
|
||||||
Construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::Construct()
|
|
||||||
{
|
|
||||||
// do one-time initialization if necessary
|
|
||||||
//********************************************************
|
|
||||||
m_rectColor=RGB(0,0,0);
|
|
||||||
//********************************************************
|
|
||||||
AfxLockGlobals(CRIT_RECTTRACKER);
|
|
||||||
static BOOL bInitialized;
|
|
||||||
if (!bInitialized)
|
|
||||||
{
|
|
||||||
// sanity checks for assumptions we make in the code
|
|
||||||
ASSERT(sizeof(((RECT*)NULL)->left) == sizeof(int));
|
|
||||||
ASSERT(offsetof(RECT, top) > offsetof(RECT, left));
|
|
||||||
ASSERT(offsetof(RECT, right) > offsetof(RECT, top));
|
|
||||||
ASSERT(offsetof(RECT, bottom) > offsetof(RECT, right));
|
|
||||||
|
|
||||||
if (_afxHatchBrush == NULL)
|
|
||||||
{
|
|
||||||
// create the hatch pattern + bitmap
|
|
||||||
WORD hatchPattern[8];
|
|
||||||
WORD wPattern = 0x1111;
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
hatchPattern[i] = wPattern;
|
|
||||||
hatchPattern[i+4] = wPattern;
|
|
||||||
wPattern <<= 1;
|
|
||||||
}
|
|
||||||
HBITMAP hatchBitmap = CreateBitmap(8, 8, 1, 1, &hatchPattern);
|
|
||||||
if (hatchBitmap == NULL)
|
|
||||||
{
|
|
||||||
AfxUnlockGlobals(CRIT_RECTTRACKER);
|
|
||||||
AfxThrowResourceException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// create black hatched brush
|
|
||||||
_afxHatchBrush = CreatePatternBrush(hatchBitmap);
|
|
||||||
DeleteObject(hatchBitmap);
|
|
||||||
if (_afxHatchBrush == NULL)
|
|
||||||
{
|
|
||||||
AfxUnlockGlobals(CRIT_RECTTRACKER);
|
|
||||||
AfxThrowResourceException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//CreatePen for DottedLine and SolidLine
|
|
||||||
CreatePen();
|
|
||||||
|
|
||||||
// Note: all track cursors must live in same module
|
|
||||||
HINSTANCE hInst = AfxFindResourceHandle(
|
|
||||||
MAKEINTRESOURCE(AFX_IDC_TRACK4WAY), RT_GROUP_CURSOR);
|
|
||||||
|
|
||||||
// initialize the cursor array
|
|
||||||
_afxCursors[0] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNWSE));
|
|
||||||
_afxCursors[1] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNESW));
|
|
||||||
_afxCursors[2] = _afxCursors[0];
|
|
||||||
_afxCursors[3] = _afxCursors[1];
|
|
||||||
_afxCursors[4] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKNS));
|
|
||||||
_afxCursors[5] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACKWE));
|
|
||||||
_afxCursors[6] = _afxCursors[4];
|
|
||||||
_afxCursors[7] = _afxCursors[5];
|
|
||||||
_afxCursors[8] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_TRACK4WAY));
|
|
||||||
_afxCursors[9] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_MOVE4WAY));
|
|
||||||
|
|
||||||
// get default handle size from Windows profile setting
|
|
||||||
static const TCHAR szWindows[] = _T("windows");
|
|
||||||
static const TCHAR szInplaceBorderWidth[] =
|
|
||||||
_T("oleinplaceborderwidth");
|
|
||||||
_afxHandleSize = GetProfileInt(szWindows, szInplaceBorderWidth, 4);
|
|
||||||
bInitialized = TRUE;
|
|
||||||
}
|
|
||||||
AfxUnlockGlobals(CRIT_RECTTRACKER);
|
|
||||||
|
|
||||||
m_nStyle = 0;
|
|
||||||
m_nHandleSize = _afxHandleSize;
|
|
||||||
m_sizeMin.cy = m_sizeMin.cx = m_nHandleSize*2;
|
|
||||||
|
|
||||||
m_rectLast.SetRectEmpty();
|
|
||||||
m_sizeLast.cx = m_sizeLast.cy = 0;
|
|
||||||
m_bErase = FALSE;
|
|
||||||
m_bFinalErase = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
CMyTracker::~CMyTracker()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CMyTracker operations
|
|
||||||
|
|
||||||
void CMyTracker::Draw(CDC* pDC) const
|
|
||||||
{
|
|
||||||
// set initial DC state
|
|
||||||
VERIFY(pDC->SaveDC() != 0);
|
|
||||||
pDC->SetMapMode(MM_TEXT);
|
|
||||||
pDC->SetViewportOrg(0, 0);
|
|
||||||
pDC->SetWindowOrg(0, 0);
|
|
||||||
|
|
||||||
// get normalized rectangle
|
|
||||||
CRect rect = m_rect;
|
|
||||||
rect.NormalizeRect();
|
|
||||||
|
|
||||||
CPen* pOldPen = NULL;
|
|
||||||
CBrush* pOldBrush = NULL;
|
|
||||||
CGdiObject* pTemp;
|
|
||||||
int nOldROP;
|
|
||||||
|
|
||||||
// draw lines
|
|
||||||
if ((m_nStyle & (dottedLine|solidLine)) != 0)
|
|
||||||
{
|
|
||||||
if (m_nStyle & dottedLine)
|
|
||||||
{
|
|
||||||
//改变当前矩形颜色
|
|
||||||
pOldPen = pDC->SelectObject(CPen::FromHandle(_afxBlackDottedPen));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//改变当前矩形颜色
|
|
||||||
//pOldPen = (CPen*)pDC->SelectStockObject(BLACK_PEN); //BLACK_PEN
|
|
||||||
pOldPen = pDC->SelectObject(CPen::FromHandle(_afxBlackSolidPen));
|
|
||||||
}
|
|
||||||
|
|
||||||
pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
|
|
||||||
nOldROP = pDC->SetROP2(R2_COPYPEN);
|
|
||||||
rect.InflateRect(+1, +1); // borders are one pixel outside
|
|
||||||
pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
|
|
||||||
pDC->SetROP2(nOldROP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if hatchBrush is going to be used, need to unrealize it
|
|
||||||
if ((m_nStyle & (hatchInside|hatchedBorder)) != 0)
|
|
||||||
UnrealizeObject(_afxHatchBrush);
|
|
||||||
|
|
||||||
// hatch inside
|
|
||||||
if ((m_nStyle & hatchInside) != 0)
|
|
||||||
{
|
|
||||||
pTemp = pDC->SelectStockObject(NULL_PEN);
|
|
||||||
if (pOldPen == NULL)
|
|
||||||
pOldPen = (CPen*)pTemp;
|
|
||||||
pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
|
|
||||||
if (pOldBrush == NULL)
|
|
||||||
pOldBrush = (CBrush*)pTemp;
|
|
||||||
pDC->SetBkMode(TRANSPARENT);
|
|
||||||
nOldROP = pDC->SetROP2(R2_MASKNOTPEN);
|
|
||||||
pDC->Rectangle(rect.left+1, rect.top+1, rect.right, rect.bottom);
|
|
||||||
pDC->SetROP2(nOldROP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw hatched border
|
|
||||||
if ((m_nStyle & hatchedBorder) != 0)
|
|
||||||
{
|
|
||||||
pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
|
|
||||||
if (pOldBrush == NULL)
|
|
||||||
pOldBrush = (CBrush*)pTemp;
|
|
||||||
pDC->SetBkMode(OPAQUE);
|
|
||||||
CRect rectTrue;
|
|
||||||
GetTrueRect(&rectTrue);
|
|
||||||
pDC->PatBlt(rectTrue.left, rectTrue.top, rectTrue.Width(),
|
|
||||||
rect.top-rectTrue.top, 0x000F0001 /* Pn */);
|
|
||||||
pDC->PatBlt(rectTrue.left, rect.bottom,
|
|
||||||
rectTrue.Width(), rectTrue.bottom-rect.bottom, 0x000F0001 /* Pn */);
|
|
||||||
pDC->PatBlt(rectTrue.left, rect.top, rect.left-rectTrue.left,
|
|
||||||
rect.Height(), 0x000F0001 /* Pn */);
|
|
||||||
pDC->PatBlt(rect.right, rect.top, rectTrue.right-rect.right,
|
|
||||||
rect.Height(), 0x000F0001 /* Pn */);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw resize handles
|
|
||||||
if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
|
|
||||||
{
|
|
||||||
UINT mask = GetHandleMask();
|
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
if (mask & (1<<i))
|
|
||||||
{
|
|
||||||
GetHandleRect((TrackerHit)i, &rect);
|
|
||||||
//改变当前调整手柄矩形颜色,也就是那八个点
|
|
||||||
pDC->FillSolidRect(rect, m_rectColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup pDC state
|
|
||||||
if (pOldPen != NULL)
|
|
||||||
pDC->SelectObject(pOldPen);
|
|
||||||
if (pOldBrush != NULL)
|
|
||||||
pDC->SelectObject(pOldBrush);
|
|
||||||
VERIFY(pDC->RestoreDC(-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyTracker::SetCursor(CWnd* pWnd, UINT nHitTest) const
|
|
||||||
{
|
|
||||||
// trackers should only be in client area
|
|
||||||
if (nHitTest != HTCLIENT)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// convert cursor position to client co-ordinates
|
|
||||||
CPoint point;
|
|
||||||
GetCursorPos(&point);
|
|
||||||
pWnd->ScreenToClient(&point);
|
|
||||||
|
|
||||||
// do hittest and normalize hit
|
|
||||||
int nHandle = HitTestHandles(point);
|
|
||||||
if (nHandle < 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
// need to normalize the hittest such that we get proper cursors
|
|
||||||
nHandle = NormalizeHit(nHandle);
|
|
||||||
|
|
||||||
// handle special case of hitting area between handles
|
|
||||||
// (logically the same -- handled as a move -- but different cursor)
|
|
||||||
if (nHandle == hitMiddle && !m_rect.PtInRect(point))
|
|
||||||
{
|
|
||||||
// only for trackers with hatchedBorder (ie. in-place resizing)
|
|
||||||
if (m_nStyle & hatchedBorder)
|
|
||||||
nHandle = (TrackerHit)9;
|
|
||||||
}
|
|
||||||
|
|
||||||
//ASSERT(nHandle < _countof(_afxCursors));
|
|
||||||
::SetCursor(_afxCursors[nHandle]);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CMyTracker::HitTest(CPoint point) const
|
|
||||||
{
|
|
||||||
TrackerHit hitResult = hitNothing;
|
|
||||||
|
|
||||||
CRect rectTrue;
|
|
||||||
GetTrueRect(&rectTrue);
|
|
||||||
ASSERT(rectTrue.left <= rectTrue.right);
|
|
||||||
ASSERT(rectTrue.top <= rectTrue.bottom);
|
|
||||||
if (rectTrue.PtInRect(point))
|
|
||||||
{
|
|
||||||
if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
|
|
||||||
hitResult = (TrackerHit)HitTestHandles(point);
|
|
||||||
else
|
|
||||||
hitResult = hitMiddle;
|
|
||||||
}
|
|
||||||
return hitResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CMyTracker::NormalizeHit(int nHandle) const
|
|
||||||
{
|
|
||||||
ASSERT(nHandle <= 8 && nHandle >= -1);
|
|
||||||
if (nHandle == hitMiddle || nHandle == hitNothing)
|
|
||||||
return nHandle;
|
|
||||||
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
|
|
||||||
if (m_rect.Width() < 0)
|
|
||||||
{
|
|
||||||
nHandle = (TrackerHit)pHandleInfo->nInvertX;
|
|
||||||
pHandleInfo = &_afxHandleInfo[nHandle];
|
|
||||||
}
|
|
||||||
if (m_rect.Height() < 0)
|
|
||||||
nHandle = (TrackerHit)pHandleInfo->nInvertY;
|
|
||||||
return nHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyTracker::Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert,
|
|
||||||
CWnd* pWndClipTo)
|
|
||||||
{
|
|
||||||
// perform hit testing on the handles
|
|
||||||
int nHandle = HitTestHandles(point);
|
|
||||||
if (nHandle < 0)
|
|
||||||
{
|
|
||||||
// didn't hit a handle, so just return FALSE
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, call helper function to do the tracking
|
|
||||||
m_bAllowInvert = bAllowInvert;
|
|
||||||
return TrackHandle(nHandle, pWnd, point, pWndClipTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyTracker::TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert)
|
|
||||||
{
|
|
||||||
// simply call helper function to track from bottom right handle
|
|
||||||
m_bAllowInvert = bAllowInvert;
|
|
||||||
m_rect.SetRect(point.x, point.y, point.x, point.y);
|
|
||||||
return TrackHandle(hitBottomRight, pWnd, point, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::DrawTrackerRect(
|
|
||||||
LPCRECT lpRect, CWnd* pWndClipTo, CDC* pDC, CWnd* pWnd)
|
|
||||||
{
|
|
||||||
// first, normalize the rectangle for drawing
|
|
||||||
|
|
||||||
/*CRect rect = *lpRect;
|
|
||||||
rect.NormalizeRect();
|
|
||||||
|
|
||||||
// convert to client coordinates
|
|
||||||
if (pWndClipTo != NULL)
|
|
||||||
{
|
|
||||||
pWnd->ClientToScreen(&rect);
|
|
||||||
pWndClipTo->ScreenToClient(&rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
CSize size(0, 0);
|
|
||||||
if (!m_bFinalErase)
|
|
||||||
{
|
|
||||||
// otherwise, size depends on the style
|
|
||||||
if (m_nStyle & hatchedBorder)
|
|
||||||
{
|
|
||||||
size.cx = size.cy = max(1, GetHandleSize(rect)-1);
|
|
||||||
rect.InflateRect(size);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size.cx = CX_BORDER;
|
|
||||||
size.cy = CY_BORDER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// and draw it
|
|
||||||
if (m_bFinalErase || !m_bErase)
|
|
||||||
{
|
|
||||||
pDC->DrawDragRect(rect, size, m_rectLast, m_sizeLast);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remember last rectangles
|
|
||||||
m_rectLast = rect;
|
|
||||||
m_sizeLast = size;
|
|
||||||
*/
|
|
||||||
//此函数是画调整大小和位置时画虚线
|
|
||||||
//由于本程序不需要,如果要正常使作的话把上面注示去掉就行了!
|
|
||||||
((CCatchScreenDlg *)pWnd)->InvalidateRgnWindow();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::AdjustRect(int nHandle, LPRECT)
|
|
||||||
{
|
|
||||||
if (nHandle == hitMiddle)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// convert the handle into locations within m_rect
|
|
||||||
int *px, *py;
|
|
||||||
GetModifyPointers(nHandle, &px, &py, NULL, NULL);
|
|
||||||
|
|
||||||
// enforce minimum width
|
|
||||||
int nNewWidth = m_rect.Width();
|
|
||||||
int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth;
|
|
||||||
if (px != NULL && nAbsWidth < m_sizeMin.cx)
|
|
||||||
{
|
|
||||||
nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
|
|
||||||
//ASSERT((int*)px - (int*)&m_rect < _countof(_afxRectInfo));
|
|
||||||
const AFX_RECTINFO* pRectInfo = &_afxRectInfo[(int*)px - (int*)&m_rect];
|
|
||||||
*px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
|
|
||||||
nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross;
|
|
||||||
}
|
|
||||||
|
|
||||||
// enforce minimum height
|
|
||||||
int nNewHeight = m_rect.Height();
|
|
||||||
int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight;
|
|
||||||
if (py != NULL && nAbsHeight < m_sizeMin.cy)
|
|
||||||
{
|
|
||||||
nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
|
|
||||||
//ASSERT((int*)py - (int*)&m_rect < _countof(_afxRectInfo));
|
|
||||||
const AFX_RECTINFO* pRectInfo = &_afxRectInfo[(int*)py - (int*)&m_rect];
|
|
||||||
*py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
|
|
||||||
nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::GetTrueRect(LPRECT lpTrueRect) const
|
|
||||||
{
|
|
||||||
ASSERT(AfxIsValidAddress(lpTrueRect, sizeof(RECT)));
|
|
||||||
|
|
||||||
CRect rect = m_rect;
|
|
||||||
rect.NormalizeRect();
|
|
||||||
int nInflateBy = 0;
|
|
||||||
if ((m_nStyle & (resizeOutside|hatchedBorder)) != 0)
|
|
||||||
nInflateBy += GetHandleSize() - 1;
|
|
||||||
if ((m_nStyle & (solidLine|dottedLine)) != 0)
|
|
||||||
++nInflateBy;
|
|
||||||
rect.InflateRect(nInflateBy, nInflateBy);
|
|
||||||
*lpTrueRect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::OnChangedRect(const CRect& /*rectOld*/)
|
|
||||||
{
|
|
||||||
// no default implementation, useful for derived classes
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CMyTracker implementation helpers
|
|
||||||
|
|
||||||
void CMyTracker::GetHandleRect(int nHandle, CRect* pHandleRect) const
|
|
||||||
{
|
|
||||||
ASSERT(nHandle < 8);
|
|
||||||
|
|
||||||
// get normalized rectangle of the tracker
|
|
||||||
CRect rectT = m_rect;
|
|
||||||
rectT.NormalizeRect();
|
|
||||||
if ((m_nStyle & (solidLine|dottedLine)) != 0)
|
|
||||||
rectT.InflateRect(+1, +1);
|
|
||||||
|
|
||||||
// since the rectangle itself was normalized, we also have to invert the
|
|
||||||
// resize handles.
|
|
||||||
nHandle = NormalizeHit(nHandle);
|
|
||||||
|
|
||||||
// handle case of resize handles outside the tracker
|
|
||||||
int size = GetHandleSize();
|
|
||||||
|
|
||||||
if(m_nStyle & resizeOutside)
|
|
||||||
{
|
|
||||||
if(1000000 & m_nStyle)
|
|
||||||
{
|
|
||||||
rectT.InflateRect(size-size/2-1, size-size/2-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rectT.InflateRect(size-1, size-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate position of the resize handle
|
|
||||||
int nWidth = rectT.Width();
|
|
||||||
int nHeight = rectT.Height();
|
|
||||||
CRect rect;
|
|
||||||
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
|
|
||||||
rect.left = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetX);
|
|
||||||
rect.top = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetY);
|
|
||||||
rect.left += size * pHandleInfo->nHandleX;
|
|
||||||
rect.top += size * pHandleInfo->nHandleY;
|
|
||||||
rect.left += pHandleInfo->nCenterX * (nWidth - size) / 2;
|
|
||||||
rect.top += pHandleInfo->nCenterY * (nHeight - size) / 2;
|
|
||||||
rect.right = rect.left + size;
|
|
||||||
rect.bottom = rect.top + size;
|
|
||||||
|
|
||||||
*pHandleRect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CMyTracker::GetHandleSize(LPCRECT lpRect) const
|
|
||||||
{
|
|
||||||
if (lpRect == NULL)
|
|
||||||
lpRect = &m_rect;
|
|
||||||
|
|
||||||
int size = m_nHandleSize;
|
|
||||||
if (!(m_nStyle & resizeOutside))
|
|
||||||
{
|
|
||||||
// make sure size is small enough for the size of the rect
|
|
||||||
int sizeMax = min(abs(lpRect->right - lpRect->left),
|
|
||||||
abs(lpRect->bottom - lpRect->top));
|
|
||||||
if (size * 2 > sizeMax)
|
|
||||||
size = sizeMax / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CMyTracker::HitTestHandles(CPoint point) const
|
|
||||||
{
|
|
||||||
CRect rect;
|
|
||||||
UINT mask = GetHandleMask();
|
|
||||||
|
|
||||||
// see if hit anywhere inside the tracker
|
|
||||||
GetTrueRect(&rect);
|
|
||||||
if (!rect.PtInRect(point))
|
|
||||||
return hitNothing; // totally missed
|
|
||||||
|
|
||||||
// see if we hit a handle
|
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
{
|
|
||||||
if (mask & (1<<i))
|
|
||||||
{
|
|
||||||
GetHandleRect((TrackerHit)i, &rect);
|
|
||||||
if (rect.PtInRect(point))
|
|
||||||
return (TrackerHit)i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// last of all, check for non-hit outside of object, between resize handles
|
|
||||||
if ((m_nStyle & hatchedBorder) == 0)
|
|
||||||
{
|
|
||||||
CRect rect = m_rect;
|
|
||||||
rect.NormalizeRect();
|
|
||||||
if ((m_nStyle & dottedLine|solidLine) != 0)
|
|
||||||
rect.InflateRect(+1, +1);
|
|
||||||
if (!rect.PtInRect(point))
|
|
||||||
return hitNothing; // must have been between resize handles
|
|
||||||
}
|
|
||||||
return hitMiddle; // no handle hit, but hit object (or object border)
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CMyTracker::TrackHandle(int nHandle, CWnd* pWnd, CPoint point,
|
|
||||||
CWnd* pWndClipTo)
|
|
||||||
{
|
|
||||||
ASSERT(nHandle >= 0);
|
|
||||||
ASSERT(nHandle <= 8); // handle 8 is inside the rect
|
|
||||||
|
|
||||||
// don't handle if capture already set
|
|
||||||
if (::GetCapture() != NULL)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
AfxLockTempMaps(); // protect maps while looping
|
|
||||||
|
|
||||||
ASSERT(!m_bFinalErase);
|
|
||||||
|
|
||||||
// save original width & height in pixels
|
|
||||||
int nWidth = m_rect.Width();
|
|
||||||
int nHeight = m_rect.Height();
|
|
||||||
|
|
||||||
// set capture to the window which received this message
|
|
||||||
pWnd->SetCapture();
|
|
||||||
ASSERT(pWnd == CWnd::GetCapture());
|
|
||||||
pWnd->UpdateWindow();
|
|
||||||
if (pWndClipTo != NULL)
|
|
||||||
pWndClipTo->UpdateWindow();
|
|
||||||
CRect rectSave = m_rect;
|
|
||||||
|
|
||||||
// find out what x/y coords we are supposed to modify
|
|
||||||
int *px, *py;
|
|
||||||
int xDiff, yDiff;
|
|
||||||
GetModifyPointers(nHandle, &px, &py, &xDiff, &yDiff);
|
|
||||||
xDiff = point.x - xDiff;
|
|
||||||
yDiff = point.y - yDiff;
|
|
||||||
|
|
||||||
// get DC for drawing
|
|
||||||
CDC* pDrawDC;
|
|
||||||
if (pWndClipTo != NULL)
|
|
||||||
{
|
|
||||||
// clip to arbitrary window by using adjusted Window DC
|
|
||||||
pDrawDC = pWndClipTo->GetDCEx(NULL, DCX_CACHE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// otherwise, just use normal DC
|
|
||||||
pDrawDC = pWnd->GetDC();
|
|
||||||
}
|
|
||||||
ASSERT_VALID(pDrawDC);
|
|
||||||
|
|
||||||
CRect rectOld;
|
|
||||||
BOOL bMoved = FALSE;
|
|
||||||
|
|
||||||
// get messages until capture lost or cancelled/accepted
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
MSG msg;
|
|
||||||
VERIFY(::GetMessage(&msg, NULL, 0, 0));
|
|
||||||
|
|
||||||
if (CWnd::GetCapture() != pWnd)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//增加的,把消息派送给窗口
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
|
|
||||||
switch (msg.message)
|
|
||||||
{
|
|
||||||
// handle movement/accept messages
|
|
||||||
case WM_LBUTTONUP:
|
|
||||||
case WM_MOUSEMOVE:
|
|
||||||
rectOld = m_rect;
|
|
||||||
// handle resize cases (and part of move)
|
|
||||||
if (px != NULL)
|
|
||||||
*px = (int)(short)LOWORD(msg.lParam) - xDiff;
|
|
||||||
if (py != NULL)
|
|
||||||
*py = (int)(short)HIWORD(msg.lParam) - yDiff;
|
|
||||||
|
|
||||||
// handle move case
|
|
||||||
if (nHandle == hitMiddle)
|
|
||||||
{
|
|
||||||
m_rect.right = m_rect.left + nWidth;
|
|
||||||
m_rect.bottom = m_rect.top + nHeight;
|
|
||||||
}
|
|
||||||
// allow caller to adjust the rectangle if necessary
|
|
||||||
AdjustRect(nHandle, &m_rect);
|
|
||||||
|
|
||||||
// only redraw and callback if the rect actually changed!
|
|
||||||
m_bFinalErase = (msg.message == WM_LBUTTONUP);
|
|
||||||
if (!rectOld.EqualRect(&m_rect) || m_bFinalErase)
|
|
||||||
{
|
|
||||||
if (bMoved)
|
|
||||||
{
|
|
||||||
m_bErase = TRUE;
|
|
||||||
DrawTrackerRect(&rectOld, pWndClipTo, pDrawDC, pWnd);
|
|
||||||
}
|
|
||||||
OnChangedRect(rectOld);
|
|
||||||
if (msg.message != WM_LBUTTONUP)
|
|
||||||
{
|
|
||||||
bMoved = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_bFinalErase)
|
|
||||||
goto ExitLoop;
|
|
||||||
|
|
||||||
if (!rectOld.EqualRect(&m_rect))
|
|
||||||
{
|
|
||||||
m_bErase = FALSE;
|
|
||||||
DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// handle cancel messages
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
if (msg.wParam != VK_ESCAPE)
|
|
||||||
break;
|
|
||||||
case WM_RBUTTONDOWN:
|
|
||||||
if (bMoved)
|
|
||||||
{
|
|
||||||
m_bErase = m_bFinalErase = TRUE;
|
|
||||||
//DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
|
|
||||||
}
|
|
||||||
m_rect = rectSave;
|
|
||||||
goto ExitLoop;
|
|
||||||
|
|
||||||
// just dispatch rest of the messages
|
|
||||||
default:
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ExitLoop:
|
|
||||||
if (pWndClipTo != NULL)
|
|
||||||
pWndClipTo->ReleaseDC(pDrawDC);
|
|
||||||
else
|
|
||||||
pWnd->ReleaseDC(pDrawDC);
|
|
||||||
ReleaseCapture();
|
|
||||||
|
|
||||||
AfxUnlockTempMaps(FALSE);
|
|
||||||
|
|
||||||
// restore rect in case bMoved is still FALSE
|
|
||||||
if (!bMoved)
|
|
||||||
m_rect = rectSave;
|
|
||||||
m_bFinalErase = FALSE;
|
|
||||||
m_bErase = FALSE;
|
|
||||||
|
|
||||||
// return TRUE only if rect has changed
|
|
||||||
return !rectSave.EqualRect(&m_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::GetModifyPointers(
|
|
||||||
int nHandle, int** ppx, int** ppy, int* px, int* py)
|
|
||||||
{
|
|
||||||
ASSERT(nHandle >= 0);
|
|
||||||
ASSERT(nHandle <= 8);
|
|
||||||
|
|
||||||
if (nHandle == hitMiddle)
|
|
||||||
nHandle = hitTopLeft; // same as hitting top-left
|
|
||||||
|
|
||||||
*ppx = NULL;
|
|
||||||
*ppy = NULL;
|
|
||||||
|
|
||||||
// fill in the part of the rect that this handle modifies
|
|
||||||
// (Note: handles that map to themselves along a given axis when that
|
|
||||||
// axis is inverted don't modify the value on that axis)
|
|
||||||
|
|
||||||
const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
|
|
||||||
if (pHandleInfo->nInvertX != nHandle)
|
|
||||||
{
|
|
||||||
*ppx = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetX);
|
|
||||||
if (px != NULL)
|
|
||||||
*px = **ppx;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// middle handle on X axis
|
|
||||||
if (px != NULL)
|
|
||||||
*px = m_rect.left + abs(m_rect.Width()) / 2;
|
|
||||||
}
|
|
||||||
if (pHandleInfo->nInvertY != nHandle)
|
|
||||||
{
|
|
||||||
*ppy = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetY);
|
|
||||||
if (py != NULL)
|
|
||||||
*py = **ppy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// middle handle on Y axis
|
|
||||||
if (py != NULL)
|
|
||||||
*py = m_rect.top + abs(m_rect.Height()) / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT CMyTracker::GetHandleMask() const
|
|
||||||
{
|
|
||||||
UINT mask = 0x0F; // always have 4 corner handles
|
|
||||||
int size = m_nHandleSize*3;
|
|
||||||
if (abs(m_rect.Width()) - size > 4)
|
|
||||||
mask |= 0x50;
|
|
||||||
if (abs(m_rect.Height()) - size > 4)
|
|
||||||
mask |= 0xA0;
|
|
||||||
return mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////增加的函数/////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void CMyTracker::SetRectColor(COLORREF rectColor)
|
|
||||||
{
|
|
||||||
m_rectColor=rectColor;
|
|
||||||
CreatePen();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::CreatePen()
|
|
||||||
{
|
|
||||||
//if (_afxBlackDottedPen == NULL)
|
|
||||||
{
|
|
||||||
// create black dotted pen
|
|
||||||
_afxBlackDottedPen = ::CreatePen(PS_DOT, 0, m_rectColor);
|
|
||||||
if (_afxBlackDottedPen == NULL)
|
|
||||||
{
|
|
||||||
AfxUnlockGlobals(CRIT_RECTTRACKER);
|
|
||||||
AfxThrowResourceException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//if (_afxBlackSolidPen == NULL)
|
|
||||||
{
|
|
||||||
// create black dotted pen
|
|
||||||
_afxBlackSolidPen = ::CreatePen(PS_SOLID, 0, m_rectColor);
|
|
||||||
if (_afxBlackSolidPen == NULL)
|
|
||||||
{
|
|
||||||
AfxUnlockGlobals(CRIT_RECTTRACKER);
|
|
||||||
AfxThrowResourceException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMyTracker::SetResizeCursor(UINT nID_N_S,UINT nID_W_E,UINT nID_NW_SE,UINT nID_NE_SW,UINT nIDMiddle)
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// N
|
|
||||||
// NW -----------|------------NE
|
|
||||||
// | |
|
|
||||||
// | |
|
|
||||||
// W | | E
|
|
||||||
// | Middle |
|
|
||||||
// | |
|
|
||||||
// | |
|
|
||||||
// SW-----------|------------SE
|
|
||||||
// S
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
_afxCursors[0] = AfxGetApp()->LoadCursor(nID_NW_SE); //nw
|
|
||||||
_afxCursors[1] = AfxGetApp()->LoadCursor(nID_NE_SW); //ne
|
|
||||||
_afxCursors[2] = _afxCursors[0]; //se
|
|
||||||
_afxCursors[3] = _afxCursors[1]; //sw
|
|
||||||
_afxCursors[4] = AfxGetApp()->LoadCursor(nID_N_S); //n
|
|
||||||
_afxCursors[5] = AfxGetApp()->LoadCursor(nID_W_E); //w
|
|
||||||
_afxCursors[6] = _afxCursors[4]; //s
|
|
||||||
_afxCursors[7] = _afxCursors[5]; //e
|
|
||||||
_afxCursors[8] = AfxGetApp()->LoadCursor(nIDMiddle); //m
|
|
||||||
// _afxCursors[9] = ::LoadCursor(hInst, MAKEINTRESOURCE(AFX_IDC_MOVE4WAY));
|
|
||||||
}
|
|
@ -1,102 +0,0 @@
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// CMyTracker - simple rectangular tracking rectangle w/resize handles
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// Copy from MFC CRectTracker class
|
|
||||||
// Add Some member function
|
|
||||||
// Modify some place
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define MYTRACKER_
|
|
||||||
|
|
||||||
#define CX_BORDER 1
|
|
||||||
#define CY_BORDER 1
|
|
||||||
|
|
||||||
#define CRIT_RECTTRACKER 5
|
|
||||||
void AFXAPI AfxLockGlobals(int nLockType);
|
|
||||||
void AFXAPI AfxUnlockGlobals(int nLockType);
|
|
||||||
void AFXAPI AfxDeleteObject(HGDIOBJ* pObject);
|
|
||||||
|
|
||||||
class CMyTracker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Constructors
|
|
||||||
CMyTracker();
|
|
||||||
CMyTracker(LPCRECT lpSrcRect, UINT nStyle);
|
|
||||||
|
|
||||||
// Style Flags
|
|
||||||
enum StyleFlags
|
|
||||||
{
|
|
||||||
solidLine = 1, dottedLine = 2, hatchedBorder = 4,
|
|
||||||
resizeInside = 8, resizeOutside = 16, hatchInside = 32,
|
|
||||||
resizeMiddle =80 //设置中间
|
|
||||||
};
|
|
||||||
|
|
||||||
// Hit-Test codes
|
|
||||||
enum TrackerHit
|
|
||||||
{
|
|
||||||
hitNothing = -1,
|
|
||||||
hitTopLeft = 0, hitTopRight = 1, hitBottomRight = 2, hitBottomLeft = 3,
|
|
||||||
hitTop = 4, hitRight = 5, hitBottom = 6, hitLeft = 7, hitMiddle = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
// Attributes
|
|
||||||
UINT m_nStyle; // current state
|
|
||||||
CRect m_rect; // current position (always in pixels)
|
|
||||||
CSize m_sizeMin; // minimum X and Y size during track operation
|
|
||||||
int m_nHandleSize; // size of resize handles (default from WIN.INI)
|
|
||||||
|
|
||||||
// Operations
|
|
||||||
void Draw(CDC* pDC) const;
|
|
||||||
void GetTrueRect(LPRECT lpTrueRect) const;
|
|
||||||
BOOL SetCursor(CWnd* pWnd, UINT nHitTest) const;
|
|
||||||
BOOL Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert =TRUE,
|
|
||||||
CWnd* pWndClipTo = NULL);
|
|
||||||
BOOL TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert = TRUE);
|
|
||||||
int HitTest(CPoint point) const;
|
|
||||||
int NormalizeHit(int nHandle) const;
|
|
||||||
|
|
||||||
// Overridables
|
|
||||||
virtual void DrawTrackerRect(LPCRECT lpRect, CWnd* pWndClipTo,
|
|
||||||
CDC* pDC, CWnd* pWnd);
|
|
||||||
virtual void AdjustRect(int nHandle, LPRECT lpRect);
|
|
||||||
virtual void OnChangedRect(const CRect& rectOld);
|
|
||||||
virtual UINT GetHandleMask() const;
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
public:
|
|
||||||
virtual ~CMyTracker();
|
|
||||||
|
|
||||||
public:
|
|
||||||
//***********************************************************
|
|
||||||
//设置调整光标
|
|
||||||
void SetResizeCursor(UINT nID_N_S,UINT nID_W_E,UINT nID_NW_SE,
|
|
||||||
UINT nID_NE_SW,UINT nIDMiddle);
|
|
||||||
//创建军画刷,内部调用
|
|
||||||
void CreatePen();
|
|
||||||
//设置矩形颜色
|
|
||||||
void SetRectColor(COLORREF rectColor);
|
|
||||||
|
|
||||||
//**************************************************************
|
|
||||||
|
|
||||||
//**************************************************************
|
|
||||||
//当前矩形颜色
|
|
||||||
COLORREF m_rectColor;
|
|
||||||
//**************************************************************
|
|
||||||
BOOL m_bAllowInvert; // flag passed to Track or TrackRubberBand
|
|
||||||
CRect m_rectLast;
|
|
||||||
CSize m_sizeLast;
|
|
||||||
BOOL m_bErase; // TRUE if DrawTrackerRect is called for erasing
|
|
||||||
BOOL m_bFinalErase; // TRUE if DragTrackerRect called for final erase
|
|
||||||
|
|
||||||
// implementation helpers
|
|
||||||
int HitTestHandles(CPoint point) const;
|
|
||||||
void GetHandleRect(int nHandle, CRect* pHandleRect) const;
|
|
||||||
void GetModifyPointers(int nHandle, int**ppx, int**ppy, int* px, int*py);
|
|
||||||
virtual int GetHandleSize(LPCRECT lpRect = NULL) const;
|
|
||||||
BOOL TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo);
|
|
||||||
void Construct();
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////// END OF FILE /////////////////////////////////////////////////////////
|
|
@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (C) 2004 Jacquelin POTIER <jacquelin.potier@free.fr>
|
|
||||||
Dynamic aspect ratio code Copyright (C) 2004 Jacquelin POTIER <jacquelin.potier@free.fr>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; version 2 of the License.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Object: class helper for popupmenu control
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef _WIN32_WINNT
|
|
||||||
#define _WIN32_WINNT 0x0501 // for xp os
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
|
||||||
#pragma warning (push)
|
|
||||||
#pragma warning(disable : 4005)// for '_stprintf' : macro redefinition in tchar.h
|
|
||||||
#include <TCHAR.h>
|
|
||||||
#pragma warning (pop)
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <commctrl.h>
|
|
||||||
#pragma comment (lib,"comctl32.lib")
|
|
||||||
|
|
||||||
class CPopUpMenu
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef void (*pfMessageCallback)(WPARAM wParam, LPARAM lParam,PVOID UserParam);
|
|
||||||
CPopUpMenu();
|
|
||||||
CPopUpMenu(CPopUpMenu* ParentPopUpMenu);
|
|
||||||
~CPopUpMenu();
|
|
||||||
|
|
||||||
HMENU GetControlHandle();
|
|
||||||
CPopUpMenu* GetParentPopUpMenu();
|
|
||||||
|
|
||||||
UINT Add(TCHAR* Name);
|
|
||||||
UINT Add(TCHAR* Name,UINT Index);
|
|
||||||
UINT Add(TCHAR* Name,HICON hIcon);
|
|
||||||
UINT Add(TCHAR* Name,HICON hIcon,UINT Index);
|
|
||||||
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance);
|
|
||||||
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance,UINT Index);
|
|
||||||
UINT Add(TCHAR* Name,int IdIcon,HINSTANCE hInstance,int Width,int Height,UINT Index);
|
|
||||||
|
|
||||||
UINT AddSeparator();
|
|
||||||
UINT AddSeparator(UINT Index);
|
|
||||||
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,UINT Index);
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu);
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,int IdIcon,HINSTANCE hInstance,UINT Index);
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,int IdIcon,HINSTANCE hInstance);
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,HICON hIcon,UINT Index);
|
|
||||||
UINT AddSubMenu(TCHAR* SubMenuName,CPopUpMenu* SubMenu,HICON hIcon);
|
|
||||||
|
|
||||||
void SetCheckedState(UINT MenuID,BOOL bChecked);
|
|
||||||
BOOL IsChecked(UINT MenuID);
|
|
||||||
void SetEnabledState(UINT MenuID,BOOL bEnabled);
|
|
||||||
BOOL IsEnabled(UINT MenuID);
|
|
||||||
BOOL SetText(UINT MenuID,TCHAR* pszText);
|
|
||||||
BOOL SetIcon(UINT MenuID,int IdIcon,HINSTANCE hInstance);
|
|
||||||
BOOL SetIcon(UINT MenuID,int IdIcon,HINSTANCE hInstance,int Width,int Height);
|
|
||||||
BOOL SetIcon(UINT MenuID,HICON hIcon);
|
|
||||||
int GetText(UINT MenuID,TCHAR* pszText,int pszTextMaxSize);
|
|
||||||
CPopUpMenu* GetSubMenu(UINT MenuID);
|
|
||||||
|
|
||||||
void Remove(UINT MenuID);
|
|
||||||
|
|
||||||
int GetItemCount();
|
|
||||||
int GetID(UINT MenuIndex);
|
|
||||||
int GetIndex(UINT MenuId);
|
|
||||||
|
|
||||||
UINT Show(int x,int y, HWND hOwner);
|
|
||||||
UINT Show(int x,int y, HWND hOwner,BOOL PositionRelativeToOwner);
|
|
||||||
UINT Show(int x,int y, HWND hOwner,BOOL PositionRelativeToOwner,BOOL ShowUpper);
|
|
||||||
|
|
||||||
UINT GetNextMenuId();
|
|
||||||
UINT GetMaxMenuId();
|
|
||||||
BOOL ReplaceMenuId(UINT OldMenuID,UINT NewMenuID);
|
|
||||||
|
|
||||||
BOOL SetMouseRightButtonUpCallback(pfMessageCallback Callback,PVOID UserParam);
|
|
||||||
BOOL SetMenuSelectCallback(pfMessageCallback Callback,PVOID UserParam);
|
|
||||||
|
|
||||||
BOOL bAllowIconsEffects;
|
|
||||||
private:
|
|
||||||
CPopUpMenu* ParentPopUpMenu;
|
|
||||||
HMENU hPopUpMenu;
|
|
||||||
int CurrentMenuId;
|
|
||||||
BOOL bThemingEnabledForVistaOrNewer;
|
|
||||||
std::vector<HBITMAP> ListLoadedBitmapToFree;
|
|
||||||
|
|
||||||
pfMessageCallback MouseRightButtonUpCallback;
|
|
||||||
PVOID MouseRightButtonUpUserParam;
|
|
||||||
pfMessageCallback MenuSelectCallback;
|
|
||||||
PVOID MenuSelectUserParam;
|
|
||||||
|
|
||||||
void CommonConstructor();
|
|
||||||
void SetMenuItemBitmapInfo(MENUITEMINFO* pMenuItem,HICON hIcon);
|
|
||||||
BOOL IsSubMenu(HMENU hMenu,HMENU hSubMenu);
|
|
||||||
BOOL OnMeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis);
|
|
||||||
BOOL OnDrawItem(HWND hwnd, LPDRAWITEMSTRUCT lpdis);
|
|
||||||
void OnMouseRightButtonUp(WPARAM wParam, LPARAM lParam);
|
|
||||||
void OnMenuSelect(WPARAM wParam, LPARAM lParam);
|
|
||||||
void FreeItemMemory(UINT MenuID);
|
|
||||||
void FreeItemBitmap(UINT MenuID);
|
|
||||||
static LRESULT CALLBACK SubClassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,UINT_PTR uIdSubclass,DWORD_PTR dwRefData);
|
|
||||||
};
|
|
@ -1,174 +0,0 @@
|
|||||||
// Screenshot.cpp : 定义应用程序的类行为。
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "Screenshot.h"
|
|
||||||
#include "ScreenshotDlg.h"
|
|
||||||
#include "CatchScreenDlg.h"
|
|
||||||
#include <GdiPlus.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace Gdiplus;
|
|
||||||
#pragma comment(lib,"GdiPlus.lib")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#define new DEBUG_NEW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SHIFTED 0x8000
|
|
||||||
|
|
||||||
|
|
||||||
// CScreenshotApp
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CScreenshotApp, CWinApp)
|
|
||||||
ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
|
|
||||||
END_MESSAGE_MAP()
|
|
||||||
|
|
||||||
|
|
||||||
// CScreenshotApp 构造
|
|
||||||
|
|
||||||
CScreenshotApp::CScreenshotApp()
|
|
||||||
{
|
|
||||||
// TODO: 在此处添加构造代码,
|
|
||||||
// 将所有重要的初始化放置在 InitInstance 中
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 唯一的一个 CScreenshotApp 对象
|
|
||||||
|
|
||||||
CScreenshotApp theApp;
|
|
||||||
|
|
||||||
|
|
||||||
// CScreenshotApp 初始化
|
|
||||||
|
|
||||||
BOOL CScreenshotApp::InitInstance()
|
|
||||||
{
|
|
||||||
// 如果一个运行在 Windows XP 上的应用程序清单指定要
|
|
||||||
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
|
|
||||||
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
|
|
||||||
INITCOMMONCONTROLSEX InitCtrls;
|
|
||||||
InitCtrls.dwSize = sizeof(InitCtrls);
|
|
||||||
// 将它设置为包括所有要在应用程序中使用的
|
|
||||||
// 公共控件类。
|
|
||||||
InitCtrls.dwICC = ICC_WIN95_CLASSES;
|
|
||||||
InitCommonControlsEx(&InitCtrls);
|
|
||||||
|
|
||||||
CWinApp::InitInstance();
|
|
||||||
|
|
||||||
GdiplusStartupInput input;
|
|
||||||
GdiplusStartup(&m_gdiplusToken,&input,NULL);
|
|
||||||
|
|
||||||
AfxEnableControlContainer();
|
|
||||||
|
|
||||||
// 标准初始化
|
|
||||||
// 如果未使用这些功能并希望减小
|
|
||||||
// 最终可执行文件的大小,则应移除下列
|
|
||||||
// 不需要的特定初始化例程
|
|
||||||
// 更改用于存储设置的注册表项
|
|
||||||
// TODO: 应适当修改该字符串,
|
|
||||||
// 例如修改为公司或组织名
|
|
||||||
SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
|
|
||||||
|
|
||||||
CScreenshotDlg dlg;
|
|
||||||
m_pMainWnd = &dlg;
|
|
||||||
INT_PTR nResponse = dlg.DoModal();
|
|
||||||
if (nResponse == IDOK)
|
|
||||||
{
|
|
||||||
// TODO: 在此放置处理何时用
|
|
||||||
// “确定”来关闭对话框的代码
|
|
||||||
}
|
|
||||||
else if (nResponse == IDCANCEL)
|
|
||||||
{
|
|
||||||
// TODO: 在此放置处理何时用
|
|
||||||
// “取消”来关闭对话框的代码
|
|
||||||
}
|
|
||||||
|
|
||||||
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
|
|
||||||
// 而不是启动应用程序的消息泵。
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CScreenshotApp::ProcessMessageFilter(int code, LPMSG lpMsg)
|
|
||||||
{
|
|
||||||
if(m_hwndDlg != NULL)
|
|
||||||
{
|
|
||||||
// 如果消息是从对话框发出的或者其子控件发出的,就进行处理
|
|
||||||
if((lpMsg->hwnd == m_hwndDlg) || ::IsChild(m_hwndDlg, lpMsg->hwnd))
|
|
||||||
{
|
|
||||||
// 如果消息是WM_KEYDOWN,用方向键调整位置
|
|
||||||
if(lpMsg->message == WM_KEYDOWN)
|
|
||||||
{
|
|
||||||
CRect rect(0,0,0,0);
|
|
||||||
CCatchScreenDlg * pDlg=(CCatchScreenDlg *)AfxGetMainWnd();
|
|
||||||
|
|
||||||
rect = pDlg->m_rectTracker.m_rect;
|
|
||||||
|
|
||||||
if(pDlg->m_bFirstDraw)
|
|
||||||
{
|
|
||||||
//如果Shift键按下则方向键调整大小
|
|
||||||
BOOL bIsShiftDown = FALSE;
|
|
||||||
|
|
||||||
if (GetKeyState(VK_SHIFT) & SHIFTED)
|
|
||||||
bIsShiftDown = TRUE;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
switch(lpMsg->wParam)
|
|
||||||
{
|
|
||||||
case VK_UP:
|
|
||||||
|
|
||||||
//如果按下Shift,则只调整一边
|
|
||||||
if(!bIsShiftDown)
|
|
||||||
rect.top-=1;
|
|
||||||
|
|
||||||
rect.bottom-=1;
|
|
||||||
pDlg->m_rectTracker.m_rect = rect;
|
|
||||||
pDlg->InvalidateRgnWindow();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_DOWN:
|
|
||||||
rect.top+=1;
|
|
||||||
if(!bIsShiftDown)
|
|
||||||
rect.bottom+=1;
|
|
||||||
|
|
||||||
pDlg->m_rectTracker.m_rect=rect;
|
|
||||||
pDlg->InvalidateRgnWindow();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_LEFT:
|
|
||||||
if(!bIsShiftDown)
|
|
||||||
rect.left-=1;
|
|
||||||
rect.right-=1;
|
|
||||||
|
|
||||||
pDlg->m_rectTracker.m_rect=rect;
|
|
||||||
pDlg->InvalidateRgnWindow();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_RIGHT:
|
|
||||||
rect.left+=1;
|
|
||||||
if(!bIsShiftDown)
|
|
||||||
rect.right+=1;
|
|
||||||
|
|
||||||
pDlg->m_rectTracker.m_rect=rect;
|
|
||||||
pDlg->InvalidateRgnWindow();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CWinApp::ProcessMessageFilter(code, lpMsg);
|
|
||||||
}
|
|
||||||
int CScreenshotApp::ExitInstance()
|
|
||||||
{
|
|
||||||
GdiplusShutdown(m_gdiplusToken);
|
|
||||||
|
|
||||||
return CWinApp::ExitInstance();
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
// Screenshot.h : PROJECT_NAME 应用程序的主头文件
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef __AFXWIN_H__
|
|
||||||
#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "resource.h" // 主符号
|
|
||||||
|
|
||||||
// CScreenshotApp:
|
|
||||||
// 有关此类的实现,请参阅 Screenshot.cpp
|
|
||||||
//
|
|
||||||
|
|
||||||
class CScreenshotApp : public CWinApp
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CScreenshotApp();
|
|
||||||
|
|
||||||
// 重写
|
|
||||||
public:
|
|
||||||
virtual BOOL InitInstance();
|
|
||||||
|
|
||||||
|
|
||||||
HWND m_hwndDlg;
|
|
||||||
virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
|
|
||||||
|
|
||||||
// 实现
|
|
||||||
|
|
||||||
DECLARE_MESSAGE_MAP()
|
|
||||||
private:
|
|
||||||
ULONG_PTR m_gdiplusToken;
|
|
||||||
public:
|
|
||||||
virtual int ExitInstance();
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CScreenshotApp theApp;
|
|
@ -1,217 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
#include "targetver.h"
|
|
||||||
#endif
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Chinese (P.R.C.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
|
|
||||||
#pragma code_page(936)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#ifndef APSTUDIO_INVOKED\r\n"
|
|
||||||
"#include ""targetver.h""\r\n"
|
|
||||||
"#endif\r\n"
|
|
||||||
"#include ""afxres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
|
|
||||||
"#define _AFX_NO_OLE_RESOURCES\r\n"
|
|
||||||
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
|
|
||||||
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
|
|
||||||
"LANGUAGE 4, 2\r\n"
|
|
||||||
"#pragma code_page(936)\r\n"
|
|
||||||
"#include ""res\\Screenshot.rc2"" // 非 Microsoft Visual C++ 编辑的资源\r\n"
|
|
||||||
"#include ""l.CHS\\afxres.rc"" // 标准组件\r\n"
|
|
||||||
"#endif\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDR_MAINFRAME ICON "res\\Screenshot.ico"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Dialog
|
|
||||||
//
|
|
||||||
|
|
||||||
IDD_SCREENSHOT_DIALOG DIALOGEX 0, 0, 181, 59
|
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
|
||||||
CAPTION "Screenshot"
|
|
||||||
FONT 9, "MS Shell Dlg", 0, 0, 0x1
|
|
||||||
BEGIN
|
|
||||||
PUSHBUTTON "截图",IDC_BTN_START,65,22,50,14
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_DIALOGFORIMG DIALOGEX 0, 0, 169, 140
|
|
||||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP
|
|
||||||
EXSTYLE WS_EX_TRANSPARENT
|
|
||||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
|
||||||
BEGIN
|
|
||||||
EDITTEXT IDC_EDIT1,14,20,137,93,ES_MULTILINE | ES_READONLY | NOT WS_BORDER
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION 1,0,0,1
|
|
||||||
PRODUCTVERSION 1,0,0,1
|
|
||||||
FILEFLAGSMASK 0x3fL
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS 0x1L
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS 0x4L
|
|
||||||
FILETYPE 0x1L
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "080403a8"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "TODO: <公司名>"
|
|
||||||
VALUE "FileDescription", "TODO: <文件说明>"
|
|
||||||
VALUE "FileVersion", "1.0.0.1"
|
|
||||||
VALUE "InternalName", "Screenshot.exe"
|
|
||||||
VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
|
|
||||||
VALUE "OriginalFilename", "Screenshot.exe"
|
|
||||||
VALUE "ProductName", "TODO: <产品名>"
|
|
||||||
VALUE "ProductVersion", "1.0.0.1"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x804, 936
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// DESIGNINFO
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
GUIDELINES DESIGNINFO
|
|
||||||
BEGIN
|
|
||||||
IDD_SCREENSHOT_DIALOG, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 174
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 52
|
|
||||||
END
|
|
||||||
|
|
||||||
IDD_DIALOGFORIMG, DIALOG
|
|
||||||
BEGIN
|
|
||||||
LEFTMARGIN, 7
|
|
||||||
RIGHTMARGIN, 162
|
|
||||||
TOPMARGIN, 7
|
|
||||||
BOTTOMMARGIN, 133
|
|
||||||
END
|
|
||||||
END
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Bitmap
|
|
||||||
//
|
|
||||||
|
|
||||||
IDB_BITMAP_BK BITMAP "res\\brackground.bmp"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// PNG
|
|
||||||
//
|
|
||||||
|
|
||||||
IDB_ARROW PNG "res\\Arrow.png"
|
|
||||||
IDB_RECTANGLE PNG "res\\Rectangle.png"
|
|
||||||
IDB_CIRCLE PNG "res\\Circle.png"
|
|
||||||
IDB_BRUSH PNG "res\\Brush.PNG"
|
|
||||||
IDB_MOSAIC PNG "res\\Mosaic.png"
|
|
||||||
IDB_TEXT PNG "res\\Text.png"
|
|
||||||
IDB_UNDO PNG "res\\Undo.png"
|
|
||||||
IDB_SAVE PNG "res\\Save.png"
|
|
||||||
IDB_EXIT PNG "res\\Exit.png"
|
|
||||||
IDB_FINISH PNG "res\\Finish.png"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Cursor
|
|
||||||
//
|
|
||||||
|
|
||||||
IDC_CURSOR1 CURSOR "res\\arrow_m.cur"
|
|
||||||
#endif // Chinese (P.R.C.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
#define _AFX_NO_SPLITTER_RESOURCES
|
|
||||||
#define _AFX_NO_OLE_RESOURCES
|
|
||||||
#define _AFX_NO_TRACKER_RESOURCES
|
|
||||||
#define _AFX_NO_PROPERTY_RESOURCES
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
|
|
||||||
LANGUAGE 4, 2
|
|
||||||
#pragma code_page(936)
|
|
||||||
#include "res\Screenshot.rc2" // 非 Microsoft Visual C++ 编辑的资源
|
|
||||||
#include "l.CHS\afxres.rc" // 标准组件
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
|
|
@ -1,368 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="gb2312"?>
|
|
||||||
<VisualStudioProject
|
|
||||||
ProjectType="Visual C++"
|
|
||||||
Version="9.00"
|
|
||||||
Name="Screenshot"
|
|
||||||
ProjectGUID="{24E39ACB-AB81-485D-8D36-749B3F5EC1E8}"
|
|
||||||
RootNamespace="Screenshot"
|
|
||||||
Keyword="MFCProj"
|
|
||||||
TargetFrameworkVersion="196613"
|
|
||||||
>
|
|
||||||
<Platforms>
|
|
||||||
<Platform
|
|
||||||
Name="Win32"
|
|
||||||
/>
|
|
||||||
</Platforms>
|
|
||||||
<ToolFiles>
|
|
||||||
</ToolFiles>
|
|
||||||
<Configurations>
|
|
||||||
<Configuration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
UseOfMFC="2"
|
|
||||||
CharacterSet="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
MkTypLibCompatible="false"
|
|
||||||
ValidateParameters="true"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="0"
|
|
||||||
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
|
|
||||||
MinimalRebuild="true"
|
|
||||||
BasicRuntimeChecks="3"
|
|
||||||
RuntimeLibrary="3"
|
|
||||||
UsePrecompiledHeader="2"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="4"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="_DEBUG"
|
|
||||||
Culture="2052"
|
|
||||||
AdditionalIncludeDirectories="$(IntDir)"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
LinkIncremental="1"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="2"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
<Configuration
|
|
||||||
Name="Release|Win32"
|
|
||||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
|
||||||
IntermediateDirectory="$(ConfigurationName)"
|
|
||||||
ConfigurationType="1"
|
|
||||||
UseOfMFC="2"
|
|
||||||
CharacterSet="1"
|
|
||||||
WholeProgramOptimization="1"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreBuildEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCustomBuildTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXMLDataGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCWebServiceProxyGeneratorTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCMIDLTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
MkTypLibCompatible="false"
|
|
||||||
ValidateParameters="true"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
Optimization="2"
|
|
||||||
EnableIntrinsicFunctions="true"
|
|
||||||
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
|
|
||||||
MinimalRebuild="false"
|
|
||||||
RuntimeLibrary="2"
|
|
||||||
EnableFunctionLevelLinking="true"
|
|
||||||
UsePrecompiledHeader="2"
|
|
||||||
WarningLevel="3"
|
|
||||||
DebugInformationFormat="3"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManagedResourceCompilerTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCResourceCompilerTool"
|
|
||||||
PreprocessorDefinitions="NDEBUG"
|
|
||||||
Culture="2052"
|
|
||||||
AdditionalIncludeDirectories="$(IntDir)"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPreLinkEventTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCLinkerTool"
|
|
||||||
LinkIncremental="1"
|
|
||||||
GenerateDebugInformation="true"
|
|
||||||
SubSystem="2"
|
|
||||||
OptimizeReferences="2"
|
|
||||||
EnableCOMDATFolding="2"
|
|
||||||
TargetMachine="1"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCALinkTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCManifestTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCXDCMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCBscMakeTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCFxCopTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCAppVerifierTool"
|
|
||||||
/>
|
|
||||||
<Tool
|
|
||||||
Name="VCPostBuildEventTool"
|
|
||||||
/>
|
|
||||||
</Configuration>
|
|
||||||
</Configurations>
|
|
||||||
<References>
|
|
||||||
</References>
|
|
||||||
<Files>
|
|
||||||
<Filter
|
|
||||||
Name="Source Files"
|
|
||||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
|
||||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\CatchScreenDlg.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyEdit.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyToolBar.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyTracker.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\PopUpMenu.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Screenshot.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\ScreenshotDlg.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\stdafx.cpp"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Debug|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="1"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
<FileConfiguration
|
|
||||||
Name="Release|Win32"
|
|
||||||
>
|
|
||||||
<Tool
|
|
||||||
Name="VCCLCompilerTool"
|
|
||||||
UsePrecompiledHeader="1"
|
|
||||||
/>
|
|
||||||
</FileConfiguration>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Header Files"
|
|
||||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
|
||||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\CatchScreenDlg.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyEdit.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyToolBar.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\MyTracker.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\PopUpMenu.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Resource.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Screenshot.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\ScreenshotDlg.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\stdafx.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\targetver.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<Filter
|
|
||||||
Name="Resource Files"
|
|
||||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
|
||||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
|
||||||
>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Arrow.ico"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Arrow.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\arrow_m.cur"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\brackground.bmp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Brush.PNG"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Circle.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Exit.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Finish.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Mosaic.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Rectangle.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Save.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Screenshot.ico"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\Screenshot.rc"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Screenshot.rc2"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Text.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\toolbar1.bmp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\res\Undo.png"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Filter>
|
|
||||||
<File
|
|
||||||
RelativePath=".\ReadMe.txt"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
</Files>
|
|
||||||
<Globals>
|
|
||||||
<Global
|
|
||||||
Name="RESOURCE_FILE"
|
|
||||||
Value="Screenshot.rc"
|
|
||||||
/>
|
|
||||||
</Globals>
|
|
||||||
</VisualStudioProject>
|
|
@ -1,116 +0,0 @@
|
|||||||
// ScreenshotDlg.cpp : 实现文件
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "Screenshot.h"
|
|
||||||
#include "ScreenshotDlg.h"
|
|
||||||
|
|
||||||
#include "CatchScreenDlg.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
//#define new DEBUG_NEW
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// CScreenshotDlg 对话框
|
|
||||||
|
|
||||||
|
|
||||||
CScreenshotDlg::CScreenshotDlg(CWnd* pParent /*=NULL*/)
|
|
||||||
: CDialog(CScreenshotDlg::IDD, pParent)
|
|
||||||
{
|
|
||||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScreenshotDlg::DoDataExchange(CDataExchange* pDX)
|
|
||||||
{
|
|
||||||
CDialog::DoDataExchange(pDX);
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_MESSAGE_MAP(CScreenshotDlg, CDialog)
|
|
||||||
ON_WM_PAINT()
|
|
||||||
ON_WM_QUERYDRAGICON()
|
|
||||||
//}}AFX_MSG_MAP
|
|
||||||
ON_BN_CLICKED(IDC_BTN_START, &CScreenshotDlg::OnBnClickedBtnStart)
|
|
||||||
ON_WM_CTLCOLOR()
|
|
||||||
ON_WM_MOUSEMOVE()
|
|
||||||
END_MESSAGE_MAP()
|
|
||||||
|
|
||||||
|
|
||||||
// CScreenshotDlg 消息处理程序
|
|
||||||
|
|
||||||
BOOL CScreenshotDlg::OnInitDialog()
|
|
||||||
{
|
|
||||||
CDialog::OnInitDialog();
|
|
||||||
|
|
||||||
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
|
|
||||||
// 执行此操作
|
|
||||||
SetIcon(m_hIcon, TRUE); // 设置大图标
|
|
||||||
SetIcon(m_hIcon, FALSE); // 设置小图标
|
|
||||||
|
|
||||||
// TODO: 在此添加额外的初始化代码
|
|
||||||
|
|
||||||
// 使窗体在最顶层
|
|
||||||
::SetWindowPos(GetSafeHwnd(), HWND_TOPMOST, 150, 150, 0, 0,
|
|
||||||
SWP_NOMOVE|SWP_NOSIZE|SWP_NOREDRAW);
|
|
||||||
|
|
||||||
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果向对话框添加最小化按钮,则需要下面的代码
|
|
||||||
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
|
|
||||||
// 这将由框架自动完成。
|
|
||||||
|
|
||||||
void CScreenshotDlg::OnPaint()
|
|
||||||
{
|
|
||||||
if (IsIconic())
|
|
||||||
{
|
|
||||||
CPaintDC dc(this); // 用于绘制的设备上下文
|
|
||||||
|
|
||||||
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
|
||||||
|
|
||||||
// 使图标在工作区矩形中居中
|
|
||||||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
|
||||||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
|
||||||
CRect rect;
|
|
||||||
GetClientRect(&rect);
|
|
||||||
int x = (rect.Width() - cxIcon + 1) / 2;
|
|
||||||
int y = (rect.Height() - cyIcon + 1) / 2;
|
|
||||||
|
|
||||||
// 绘制图标
|
|
||||||
dc.DrawIcon(x, y, m_hIcon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CDialog::OnPaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//当用户拖动最小化窗口时系统调用此函数取得光标
|
|
||||||
//显示。
|
|
||||||
HCURSOR CScreenshotDlg::OnQueryDragIcon()
|
|
||||||
{
|
|
||||||
return static_cast<HCURSOR>(m_hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
|
||||||
// 线程函数,用来截图
|
|
||||||
//
|
|
||||||
UINT SccreenShot_Thread (LPVOID lpParam)
|
|
||||||
{
|
|
||||||
HWND hWndMain = (HWND) lpParam;
|
|
||||||
CCatchScreenDlg dlg;
|
|
||||||
dlg.DoModal();
|
|
||||||
|
|
||||||
::ShowWindow(hWndMain,SW_SHOW);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CScreenshotDlg::OnBnClickedBtnStart()
|
|
||||||
{
|
|
||||||
::ShowWindow (m_hWnd, SW_HIDE);
|
|
||||||
//使得被激活窗口出现在前景
|
|
||||||
::AfxBeginThread (SccreenShot_Thread, (LPVOID)GetSafeHwnd());
|
|
||||||
//::ShowWindow (GetSafeHwnd(), SW_SHOW);
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
// ScreenshotDlg.h : 头文件
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// CScreenshotDlg 对话框
|
|
||||||
class CScreenshotDlg : public CDialog
|
|
||||||
{
|
|
||||||
// 构造
|
|
||||||
public:
|
|
||||||
CScreenshotDlg(CWnd* pParent = NULL); // 标准构造函数
|
|
||||||
|
|
||||||
// 对话框数据
|
|
||||||
enum { IDD = IDD_SCREENSHOT_DIALOG };
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
|
|
||||||
|
|
||||||
|
|
||||||
// 实现
|
|
||||||
protected:
|
|
||||||
HICON m_hIcon;
|
|
||||||
|
|
||||||
// 生成的消息映射函数
|
|
||||||
virtual BOOL OnInitDialog();
|
|
||||||
afx_msg void OnPaint();
|
|
||||||
afx_msg HCURSOR OnQueryDragIcon();
|
|
||||||
DECLARE_MESSAGE_MAP()
|
|
||||||
public:
|
|
||||||
afx_msg void OnBnClickedBtnStart();
|
|
||||||
};
|
|
Before Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 172 B |
Before Width: | Height: | Size: 307 B |
Before Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 142 B |
Before Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 129 B |
Before Width: | Height: | Size: 171 B |
Before Width: | Height: | Size: 21 KiB |
@ -1,13 +0,0 @@
|
|||||||
//
|
|
||||||
// Screenshot.RC2 - Microsoft Visual C++ 不会直接编辑的资源
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#error 此文件不能用 Microsoft Visual C++ 编辑
|
|
||||||
#endif //APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 在此处添加手动编辑的资源...
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 195 B |
Before Width: | Height: | Size: 766 B |
Before Width: | Height: | Size: 151 KiB |
@ -1,33 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by Screenshot.rc
|
|
||||||
//
|
|
||||||
#define IDD_SCREENSHOT_DIALOG 102
|
|
||||||
#define IDR_MAINFRAME 128
|
|
||||||
#define IDD_DIALOGFORIMG 129
|
|
||||||
#define IDB_BITMAP_BK 131
|
|
||||||
#define IDB_ARROW 132
|
|
||||||
#define IDC_CURSOR1 136
|
|
||||||
#define IDB_RECTANGLE 137
|
|
||||||
#define IDB_CIRCLE 138
|
|
||||||
#define IDB_BRUSH 139
|
|
||||||
#define IDB_MOSAIC 140
|
|
||||||
#define IDB_TEXT 141
|
|
||||||
#define IDB_UNDO 142
|
|
||||||
#define IDB_SAVE 143
|
|
||||||
#define IDB_EXIT 144
|
|
||||||
#define IDB_PNG2 145
|
|
||||||
#define IDB_FINISH 145
|
|
||||||
#define IDC_BTN_START 1000
|
|
||||||
#define IDC_EDIT1 1001
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 146
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32772
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1003
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -1,7 +0,0 @@
|
|||||||
// stdafx.cpp : 只包括标准包含文件的源文件
|
|
||||||
// Screenshot.pch 将作为预编译头
|
|
||||||
// stdafx.obj 将包含预编译类型信息
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
// stdafx.h : 标准系统包含文件的包含文件,
|
|
||||||
// 或是经常使用但不常更改的
|
|
||||||
// 特定于项目的包含文件
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef _SECURE_ATL
|
|
||||||
#define _SECURE_ATL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VC_EXTRALEAN
|
|
||||||
#define VC_EXTRALEAN // 从 Windows 头中排除极少使用的资料
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "targetver.h"
|
|
||||||
|
|
||||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的
|
|
||||||
|
|
||||||
// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
|
|
||||||
#define _AFX_ALL_WARNINGS
|
|
||||||
|
|
||||||
#include <afxwin.h> // MFC 核心组件和标准组件
|
|
||||||
#include <afxext.h> // MFC 扩展
|
|
||||||
|
|
||||||
|
|
||||||
#include <afxdisp.h> // MFC 自动化类
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _AFX_NO_OLE_SUPPORT
|
|
||||||
#include <afxdtctl.h> // MFC 对 Internet Explorer 4 公共控件的支持
|
|
||||||
#endif
|
|
||||||
#ifndef _AFX_NO_AFXCMN_SUPPORT
|
|
||||||
#include <afxcmn.h> // MFC 对 Windows 公共控件的支持
|
|
||||||
#endif // _AFX_NO_AFXCMN_SUPPORT
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _UNICODE
|
|
||||||
#if defined _M_IX86
|
|
||||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
||||||
#elif defined _M_IA64
|
|
||||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
||||||
#elif defined _M_X64
|
|
||||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
||||||
#else
|
|
||||||
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// 以下宏定义要求的最低平台。要求的最低平台
|
|
||||||
// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
|
|
||||||
// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
|
|
||||||
// 正常工作。
|
|
||||||
|
|
||||||
// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
|
|
||||||
// 有关不同平台对应值的最新信息,请参考 MSDN。
|
|
||||||
#ifndef WINVER // 指定要求的最低平台是 Windows Vista。
|
|
||||||
#define WINVER 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT // 指定要求的最低平台是 Windows Vista。
|
|
||||||
#define _WIN32_WINNT 0x0600 // 将此值更改为相应的值,以适用于 Windows 的其他版本。
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32_WINDOWS // 指定要求的最低平台是 Windows 98。
|
|
||||||
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _WIN32_IE // 指定要求的最低平台是 Internet Explorer 7.0。
|
|
||||||
#define _WIN32_IE 0x0700 // 将此值更改为相应的值,以适用于 IE 的其他版本。
|
|
||||||
#endif
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
|||||||
|
### 该问题是怎么引起的?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 重现步骤
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 报错信息
|
||||||
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
|||||||
|
### 相关的Issue
|
||||||
|
|
||||||
|
|
||||||
|
### 原因(目的、解决的问题等)
|
||||||
|
|
||||||
|
|
||||||
|
### 描述(做了什么,变更了什么)
|
||||||
|
|
||||||
|
|
||||||
|
### 测试用例(新增、改动、可能影响的功能)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
@ -0,0 +1,26 @@
|
|||||||
|
# WIFI\_IOT\_APP<a name="EN-US_TOPIC_0000001132694217"></a>
|
||||||
|
|
||||||
|
- [Introduction](#section11660541593)
|
||||||
|
- [Directory Structure](#section1464106163817)
|
||||||
|
- [Repositories Involved](#section1718733212019)
|
||||||
|
|
||||||
|
## Introduction<a name="section11660541593"></a>
|
||||||
|
|
||||||
|
The WIFI\_IOT\_APP module provides sample code for iothardware, demolink, and samgr.
|
||||||
|
|
||||||
|
## Directory Structure<a name="section1464106163817"></a>
|
||||||
|
|
||||||
|
```
|
||||||
|
applications/sample/wifi-iot/ # Sample code
|
||||||
|
└── app
|
||||||
|
├── BUILD.gn # Build script
|
||||||
|
├── demolink # Sample code for integrating demolink
|
||||||
|
├── iothardware # Sample code for LED operations
|
||||||
|
├── samgr # Sample code for the service framework
|
||||||
|
└── startup
|
||||||
|
```
|
||||||
|
|
||||||
|
## Repositories Involved<a name="section1718733212019"></a>
|
||||||
|
|
||||||
|
applications\_sample\_wifi-iot
|
||||||
|
|
@ -0,0 +1,18 @@
|
|||||||
|
# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import("//build/lite/config/component/lite_component.gni")
|
||||||
|
|
||||||
|
lite_component("app") {
|
||||||
|
features = [ "cloud_to_uart:cloud_uart", ]
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
static_library("cloud_uart") {
|
||||||
|
sources = [
|
||||||
|
"app_demo_iot.c",
|
||||||
|
"cjson_init.c",
|
||||||
|
"iot_hmac.c",
|
||||||
|
"iot_log.c",
|
||||||
|
"iot_main.c",
|
||||||
|
"iot_profile.c",
|
||||||
|
"iot_sta.c",
|
||||||
|
"hal_iot_gpio_ex.c",
|
||||||
|
"hisignalling_protocol.c",
|
||||||
|
]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"./",
|
||||||
|
"//utils/native/lite/include",
|
||||||
|
"//kernel/liteos_m/kal/cmsis",
|
||||||
|
"//base/iot_hardware/peripheral/interfaces/kits",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
|
||||||
|
"//third_party/cJSON",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
|
||||||
|
"//foundation/communication/wifi_lite/interfaces/wifiservice",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [ "WITH_LWIP" ]
|
||||||
|
}
|
@ -0,0 +1,507 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_task.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <hi_wifi_api.h>
|
||||||
|
#include <hi_mux.h>
|
||||||
|
#include <hi_io.h>
|
||||||
|
#include <hi_gpio.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "iot_main.h"
|
||||||
|
#include "iot_profile.h"
|
||||||
|
#include "ohos_init.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "iot_gpio.h"
|
||||||
|
#include <hi_stdlib.h>
|
||||||
|
#include <hisignalling_protocol.h>
|
||||||
|
#include <hi_uart.h>
|
||||||
|
#include <app_demo_uart.h>
|
||||||
|
#include <iot_uart.h>
|
||||||
|
#include "iot_gpio_ex.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* attribute initiative to report */
|
||||||
|
#define TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
#define TWO_SECOND (2000)
|
||||||
|
/* oc request id */
|
||||||
|
#define CN_COMMADN_INDEX "commands/request_id="
|
||||||
|
#define WECHAT_SUBSCRIBE_control "slot_num"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel1 "slot_1"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel2 "slot_2"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel3 "slot_3"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel4 "4"
|
||||||
|
#define topic_data "YT32IOSCAL/Hi38611_mqtt/data"
|
||||||
|
#define topic_event "YT32IOSCAL/Hi38611_mqtt/event"
|
||||||
|
#define topic_control "YT32IOSCAL/Hi38611_mqtt/control"
|
||||||
|
#define human_detect_io 7
|
||||||
|
|
||||||
|
int g_ligthStatus = -1;
|
||||||
|
int control_success = 0;
|
||||||
|
char *control_flag = "failed";
|
||||||
|
char *message = NULL;
|
||||||
|
UartDefConfig uartDefConfig = {0};
|
||||||
|
//int slot1 = 20,slot2 = 20, slot3 = 20, slot4 = 20;
|
||||||
|
typedef void (*FnMsgCallBack)(hi_gpio_value val);
|
||||||
|
|
||||||
|
typedef struct FunctionCallback {
|
||||||
|
hi_bool stop;
|
||||||
|
hi_u32 conLost;
|
||||||
|
hi_u32 queueID;
|
||||||
|
hi_u32 iotTaskID;
|
||||||
|
FnMsgCallBack msgCallBack;
|
||||||
|
}FunctionCallback;
|
||||||
|
FunctionCallback g_functinoCallback;
|
||||||
|
|
||||||
|
// uart
|
||||||
|
|
||||||
|
static void Uart1GpioCOnfig(void)
|
||||||
|
{
|
||||||
|
#ifdef ROBOT_BOARD
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_UART1_RXD);
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_6, IOT_IO_FUNC_GPIO_6_UART1_TXD);
|
||||||
|
/* IOT_BOARD */
|
||||||
|
#elif defined (EXPANSION_BOARD)
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_UART1_TXD);
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_UART1_RXD);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CPU Sleep time Set */
|
||||||
|
unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return HI_ERR_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeviceConfigInit(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
|
||||||
|
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
|
||||||
|
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_control(unsigned int IO){
|
||||||
|
IoTGpioInit(IO);
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u started!\n", IO);
|
||||||
|
hi_udelay(20000);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!\n", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_start(unsigned int IO){
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u started!\n", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_stop(unsigned int IO){
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!\n", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_reinit(unsigned int IO){
|
||||||
|
IoTGpioInit(IO);
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u initialized!\n", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void all_engine_reinit(){
|
||||||
|
engine_reinit(6);
|
||||||
|
engine_reinit(7);
|
||||||
|
engine_reinit(9);
|
||||||
|
engine_reinit(10);
|
||||||
|
IOT_LOG_DEBUG("All engines initialized!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sensor_init(){
|
||||||
|
IoTGpioInit(human_detect_io);
|
||||||
|
IoSetFunc(human_detect_io, 0);
|
||||||
|
IoTGpioSetDir(human_detect_io, IOT_GPIO_DIR_IN);
|
||||||
|
IOT_LOG_DEBUG("Sensor initialized!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
|
||||||
|
{
|
||||||
|
g_functinoCallback.msgCallBack = msgCallBack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wechatControlDeviceMsg(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
DeviceConfigInit(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
|
||||||
|
// < The payload here is the json string
|
||||||
|
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)/*定义3861接收到json文件后的操作*/
|
||||||
|
{
|
||||||
|
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
|
||||||
|
printf(strstr(payload, WECHAT_SUBSCRIBE_control));
|
||||||
|
/* 云端下发命令后,板端的操作处理 */
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_control) != NULL) {
|
||||||
|
//printf(strstr(payload, WECHAT_SUBSCRIBE_control));
|
||||||
|
|
||||||
|
all_engine_reinit();
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_channel1) != NULL) {
|
||||||
|
engine_start(6);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(6);
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
control_success = 1;
|
||||||
|
control_flag = payload;
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel2) != NULL) {
|
||||||
|
engine_start(7);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(7);
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
control_success = 1;
|
||||||
|
control_flag = payload;
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel3) != NULL) {
|
||||||
|
engine_start(2);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(2);
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
control_success = 1;
|
||||||
|
control_flag = payload;
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel4) != NULL) {
|
||||||
|
engine_start(10);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(10);
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
control_success = 1;
|
||||||
|
control_flag = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return HI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DemoMsgRcvsynchronize(int qos, const char *topic, const char *payload)
|
||||||
|
{
|
||||||
|
message = payload;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* publish sample */
|
||||||
|
/*hi_void IotPublishSample(int slot1, int slot2, int slot3, int slot4)
|
||||||
|
{
|
||||||
|
// reported attribute
|
||||||
|
WeChatProfile weChatProfile = {
|
||||||
|
.subscribeType = "type",
|
||||||
|
.status.subState = "state",
|
||||||
|
.status.subReport = "reported",
|
||||||
|
.status.reportVersion = "version",
|
||||||
|
.status.Token = "clientToken",
|
||||||
|
// report motor
|
||||||
|
.reportAction.subDeviceActionMotor = "slot_1",
|
||||||
|
.reportAction.motorActionStatus = slot1, // 0 : motor off
|
||||||
|
// report temperature
|
||||||
|
.reportAction.subDeviceActionTemperature = "slot_2",
|
||||||
|
.reportAction.temperatureData = slot2, // 30 :temperature data
|
||||||
|
// report humidity
|
||||||
|
.reportAction.subDeviceActionHumidity = "slot_3",
|
||||||
|
.reportAction.humidityActionData = slot3, // humidity data
|
||||||
|
// report light_intensity
|
||||||
|
.reportAction.subDeviceActionLightIntensity = "slot_4",
|
||||||
|
.reportAction.lightIntensityActionData = slot4, // 60 : light_intensity
|
||||||
|
};
|
||||||
|
|
||||||
|
// report light
|
||||||
|
if (g_ligthStatus == HI_TRUE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 1; // 1: light on
|
||||||
|
} else if (g_ligthStatus == HI_FALSE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; // 0: light off
|
||||||
|
} else {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; // 0: light off
|
||||||
|
}
|
||||||
|
//profile report
|
||||||
|
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile1);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
|
||||||
|
// < wait if any work to do in the while
|
||||||
|
//static hi_void *DemoEntry(const char *arg)
|
||||||
|
//{
|
||||||
|
|
||||||
|
//int feedback = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*6WifiStaReadyWait();
|
||||||
|
cJsonInit();
|
||||||
|
IoTMain();
|
||||||
|
/* 云端下发回调 */
|
||||||
|
//IoTSetMsgCallback(DemoMsgRcvCallBack);
|
||||||
|
|
||||||
|
/*if (control_success == 1)
|
||||||
|
{
|
||||||
|
//Uart1GpioCOnfig();
|
||||||
|
feedback = IoTUartWrite(DEMO_UART_NUM, control_flag, 7);
|
||||||
|
printf("feedback: %d", feedback);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* 主动上报 */
|
||||||
|
/*#ifdef TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
while (1) {
|
||||||
|
// 用户可以在这调用发布函数进行发布,需要用户自己写调用函数
|
||||||
|
IotPublishSample(slot1,slot2,slot3,slot4); // 发布例程
|
||||||
|
#endif*/
|
||||||
|
//TaskMsleep(TWO_SECOND);
|
||||||
|
|
||||||
|
//return NULL;
|
||||||
|
//}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
int SetUartRecvFlag(UartRecvDef def)
|
||||||
|
{
|
||||||
|
if (def == UART_RECV_TRUE) {
|
||||||
|
uartDefConfig.g_uartReceiveFlag = HI_TRUE;
|
||||||
|
} else {
|
||||||
|
uartDefConfig.g_uartReceiveFlag = HI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uartDefConfig.g_uartReceiveFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetUartConfig(UartDefType type)
|
||||||
|
{
|
||||||
|
int receive = 0;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case UART_RECEIVE_FLAG:
|
||||||
|
receive = uartDefConfig.g_uartReceiveFlag;
|
||||||
|
break;
|
||||||
|
case UART_RECVIVE_LEN:
|
||||||
|
receive = uartDefConfig.g_uartLen;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return receive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetUartReceiveMsg(void)
|
||||||
|
{
|
||||||
|
(void)memset_s(uartDefConfig.g_receiveUartBuff, sizeof(uartDefConfig.g_receiveUartBuff),
|
||||||
|
0x0, sizeof(uartDefConfig.g_receiveUartBuff));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *GetUartReceiveMsg(void)
|
||||||
|
{
|
||||||
|
return uartDefConfig.g_receiveUartBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hi_void *UartDemoTask(char *param)
|
||||||
|
{
|
||||||
|
hi_u8 uartBuff[UART_BUFF_SIZE] = {0};
|
||||||
|
char *recBuff = NULL;
|
||||||
|
int feedback_1 = 0;
|
||||||
|
int feedback_2 = 0;
|
||||||
|
int length = 0;
|
||||||
|
unsigned char *detect_flag = "start";
|
||||||
|
unsigned char *data_send = "jdata";
|
||||||
|
IotGpioValue value = IOT_GPIO_VALUE0;
|
||||||
|
|
||||||
|
hi_unref_param(param);
|
||||||
|
printf("Initialize uart demo successfully, please enter some datas via DEMO_UART_NUM port...\n");
|
||||||
|
Uart1GpioCOnfig();
|
||||||
|
Sensor_init();
|
||||||
|
printf("Please wait for 60 seconds for the system to start...\n");
|
||||||
|
TaskMsleep(60000);
|
||||||
|
printf("Done!\n");
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
int isTimeOut = 0;
|
||||||
|
|
||||||
|
IoTGpioGetInputVal(human_detect_io, &value);
|
||||||
|
|
||||||
|
if(value == IOT_GPIO_VALUE1)
|
||||||
|
{
|
||||||
|
//get from cloud and send to 3516
|
||||||
|
IoTUartWrite(DEMO_UART_NUM, detect_flag, 5);
|
||||||
|
IoTSetMsgCallback(DemoMsgRcvsynchronize);
|
||||||
|
//start to work
|
||||||
|
feedback_1 = IoTUartWrite(DEMO_UART_NUM, detect_flag, 5);//
|
||||||
|
printf("uart feedback %d\n", feedback_1);
|
||||||
|
|
||||||
|
//TaskMsleep(20);
|
||||||
|
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
|
||||||
|
int waitCount = 0;
|
||||||
|
while (!((uartDefConfig.g_uartLen > 0) && (uartBuff[0] == 0xaa) && (uartBuff[1] == 0x55))) {
|
||||||
|
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
|
||||||
|
TaskMsleep(50);
|
||||||
|
waitCount += 1;
|
||||||
|
if(waitCount > 400){
|
||||||
|
isTimeOut = 1;
|
||||||
|
printf("Timeout!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(isTimeOut)
|
||||||
|
continue;
|
||||||
|
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_FALSE) {
|
||||||
|
(void)memcpy_s(uartDefConfig.g_receiveUartBuff, uartDefConfig.g_uartLen,
|
||||||
|
uartBuff, uartDefConfig.g_uartLen);/*uartBuff中的信息放到uartDefConfig.g_receiveUartBuff*/
|
||||||
|
(void)SetUartRecvFlag(UART_RECV_TRUE);
|
||||||
|
}
|
||||||
|
printf("UART start\n");
|
||||||
|
printf("len:%d\n", uartDefConfig.g_uartLen);
|
||||||
|
recBuff = (char*)malloc(uartDefConfig.g_uartLen-3);
|
||||||
|
|
||||||
|
for (int i = 0; i<uartDefConfig.g_uartLen; i++)
|
||||||
|
{
|
||||||
|
if(i <= 2)
|
||||||
|
{
|
||||||
|
printf("0x%x ", uartBuff[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%c ", uartBuff[i]);
|
||||||
|
recBuff[i-3] = uartBuff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//TaskMsleep(20); /* 20:sleep 20ms */
|
||||||
|
|
||||||
|
/*send to cloud*/
|
||||||
|
|
||||||
|
IoTProfilePropertyReport_uart(CONFIG_USER_ID, recBuff);
|
||||||
|
//printf("communicatuon completed\n");
|
||||||
|
free(recBuff);
|
||||||
|
TaskMsleep(50);
|
||||||
|
IoTSetMsgCallback(DemoMsgRcvCallBack);
|
||||||
|
while (control_success == 0)
|
||||||
|
{
|
||||||
|
TaskMsleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
length = strlen(control_flag);
|
||||||
|
char len = length+'0';
|
||||||
|
IoTUartWrite(DEMO_UART_NUM, len, strlen(len));
|
||||||
|
TaskMsleep(10);
|
||||||
|
feedback_2 = IoTUartWrite(DEMO_UART_NUM, control_flag, length);
|
||||||
|
printf("feedback: %d\n", feedback_2);
|
||||||
|
|
||||||
|
}
|
||||||
|
TaskMsleep(50);
|
||||||
|
}
|
||||||
|
return HI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This demo simply shows how to read datas from UART2 port and then echo back.
|
||||||
|
*/
|
||||||
|
/*hi_void UartTransmit(hi_void)
|
||||||
|
{
|
||||||
|
hi_u32 ret = 0;
|
||||||
|
|
||||||
|
IotUartAttribute uartAttr = {
|
||||||
|
.baudRate = 115200, /* baudRate: 115200
|
||||||
|
.dataBits = 8, /* dataBits: 8bits
|
||||||
|
.stopBits = 1, /* stop bit
|
||||||
|
.parity = 0,
|
||||||
|
};
|
||||||
|
/* Initialize uart driver
|
||||||
|
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
|
||||||
|
if (ret != HI_ERR_SUCCESS) {
|
||||||
|
printf("Failed to init uart! Err code = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Create a task to handle uart communication
|
||||||
|
osThreadAttr_t attr = {0};
|
||||||
|
attr.attr_bits = 0U;
|
||||||
|
attr.cb_mem = NULL;
|
||||||
|
attr.cb_size = 0U;
|
||||||
|
attr.stack_mem = NULL;
|
||||||
|
attr.stack_size = 8096;
|
||||||
|
attr.priority = UART_DEMO_TASK_PRIORITY;
|
||||||
|
attr.name = (hi_char*)"uart demo";
|
||||||
|
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
|
||||||
|
printf("Falied to create uart demo task!\n");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
//SYS_RUN(UartTransmit);
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// < This is the demo entry, we create a task here,
|
||||||
|
// and all the works has been done in the demo_entry
|
||||||
|
#define CN_IOT_TASK_STACKSIZE 0x1000
|
||||||
|
#define CN_IOT_TASK_PRIOR 25
|
||||||
|
#define CN_IOT_TASK_NAME "IOTDEMO"
|
||||||
|
|
||||||
|
static void AppDemoIot(void)
|
||||||
|
{
|
||||||
|
hi_u32 ret = 0;
|
||||||
|
|
||||||
|
IotUartAttribute uartAttr = {
|
||||||
|
.baudRate = 115200, /* baudRate: 115200 */
|
||||||
|
.dataBits = 8, /* dataBits: 8bits */
|
||||||
|
.stopBits = 1, /* stop bit */
|
||||||
|
.parity = 0,
|
||||||
|
};
|
||||||
|
/* Initialize uart driver */
|
||||||
|
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
|
||||||
|
if (ret != HI_ERR_SUCCESS) {
|
||||||
|
printf("Failed to init uart! Err code = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osThreadAttr_t attr;
|
||||||
|
IoTWatchDogDisable();
|
||||||
|
WifiStaReadyWait();
|
||||||
|
cJsonInit();
|
||||||
|
IoTMain();
|
||||||
|
|
||||||
|
attr.name = "IOTDEMO";
|
||||||
|
attr.attr_bits = 0U;
|
||||||
|
attr.cb_mem = NULL;
|
||||||
|
attr.cb_size = 0U;
|
||||||
|
attr.stack_mem = NULL;
|
||||||
|
attr.stack_size = CN_IOT_TASK_STACKSIZE;
|
||||||
|
attr.priority = CN_IOT_TASK_PRIOR;
|
||||||
|
|
||||||
|
|
||||||
|
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
|
||||||
|
printf("Falied to create uart demo task!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_RUN(AppDemoIot);
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APP_DEMO_UART_H
|
||||||
|
#define APP_DEMO_UART_H
|
||||||
|
|
||||||
|
#define UART_BUFF_SIZE 1024
|
||||||
|
#define WRITE_BY_INT
|
||||||
|
#define UART_DEMO_TASK_STAK_SIZE 2048
|
||||||
|
#define UART_DEMO_TASK_PRIORITY 25
|
||||||
|
#define DEMO_UART_NUM HI_UART_IDX_1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_RECEIVE_FLAG = 0,
|
||||||
|
UART_RECVIVE_LEN,
|
||||||
|
UART_SEND_FLAG = 2,
|
||||||
|
UART_SEND_LEN
|
||||||
|
}UartDefType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_RECV_TRUE = 0,
|
||||||
|
UART_RECV_FALSE,
|
||||||
|
}UartRecvDef;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int uartChannel;
|
||||||
|
unsigned char g_receiveUartBuff[UART_BUFF_SIZE];
|
||||||
|
int g_uartReceiveFlag;
|
||||||
|
int g_uartLen;
|
||||||
|
}UartDefConfig;
|
||||||
|
|
||||||
|
int SetUartRecvFlag(UartRecvDef def);
|
||||||
|
int GetUartConfig(UartDefType type);
|
||||||
|
void ResetUartReceiveMsg(void);
|
||||||
|
unsigned char *GetUartReceiveMsg(void);
|
||||||
|
#endif
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cJSON.h>
|
||||||
|
#include <hi_mem.h>
|
||||||
|
|
||||||
|
static void *cJsonMalloc(size_t sz)
|
||||||
|
{
|
||||||
|
return hi_malloc(0, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cJsonFree(const char *p)
|
||||||
|
{
|
||||||
|
hi_free(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cJsonInit(void)
|
||||||
|
{
|
||||||
|
cJSON_Hooks hooks;
|
||||||
|
hooks.malloc_fn = cJsonMalloc;
|
||||||
|
hooks.free_fn = cJsonFree;
|
||||||
|
cJSON_InitHooks(&hooks);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "iot_errno.h"
|
||||||
|
#include "iot_gpio_ex.h"
|
||||||
|
#include "hi_gpio.h"
|
||||||
|
#include "hi_io.h"
|
||||||
|
#include "hi_task.h"
|
||||||
|
#include "hi_types_base.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int IoSetPull(unsigned int id, IotIoPull val)
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int IoSetFunc(unsigned int id, unsigned char val)
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_func((hi_io_name)id, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}*/
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_CONFIG_H
|
||||||
|
#define IOT_CONFIG_H
|
||||||
|
|
||||||
|
// <CONFIG THE LOG
|
||||||
|
/* if you need the iot log for the development , please enable it, else please comment it */
|
||||||
|
#define CONFIG_LINKLOG_ENABLE 1
|
||||||
|
|
||||||
|
// < CONFIG THE WIFI
|
||||||
|
/* Please modify the ssid and pwd for the own */
|
||||||
|
#define CONFIG_AP_SSID "Metro" // WIFI SSID
|
||||||
|
#define CONFIG_AP_PWD "12364987" // WIFI PWD
|
||||||
|
/* Tencent iot Cloud user ID , password */
|
||||||
|
#define CONFIG_USER_ID "YT32IOSCALHi38611_mqtt;12010126;41883;1663689600"
|
||||||
|
#define CONFIG_USER_PWD "b4168d5d4b65898e6984346c81ad13e1b3f112ab7ce46f65cf29455f4c9e18e8;hmacsha256"
|
||||||
|
#define CN_CLIENTID "YT32IOSCALHi38611_mqtt" // Tencent cloud ClientID format: Product ID + device name
|
||||||
|
#endif
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file make use the hmac to make mqtt pwd.
|
||||||
|
* The method is use the date string to hash the device passwd
|
||||||
|
* Take care that this implement depends on the hmac of the mbedtls
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "md.h"
|
||||||
|
#include "md_internal.h"
|
||||||
|
|
||||||
|
#define CN_HMAC256_LEN_MAX (65)
|
||||||
|
#define CN_HMAC256_LEN 32
|
||||||
|
#define RIGHT_MOVE_BIT_4 (4)
|
||||||
|
#define NUMBER_9 (9)
|
||||||
|
#define DECIMAL_BASE (10)
|
||||||
|
#define STRING_LEN_TIMES (2)
|
||||||
|
#define LEN_TIMES (2)
|
||||||
|
#define OFFSET (1)
|
||||||
|
// make a byte to 2 ascii hex
|
||||||
|
static int byte2hexstr(unsigned char *bufin, int len, char *bufout)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
unsigned char tmp_l = 0x0;
|
||||||
|
unsigned char tmp_h = 0;
|
||||||
|
if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
|
||||||
|
tmp_l = bufin[i] & 0x0F;
|
||||||
|
bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
|
||||||
|
(tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
|
||||||
|
bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
|
||||||
|
(tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
|
||||||
|
}
|
||||||
|
bufout[STRING_LEN_TIMES * len] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
|
||||||
|
int keyLen, unsigned char *buf)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
mbedtls_md_context_t mbedtls_md_ctx;
|
||||||
|
const mbedtls_md_info_t *md_info;
|
||||||
|
unsigned char hash[CN_HMAC256_LEN];
|
||||||
|
|
||||||
|
if ((key == NULL)||(content == NULL)||(buf == NULL)||
|
||||||
|
(keyLen == 0)||(contentLen == 0)||
|
||||||
|
(CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(&mbedtls_md_ctx);
|
||||||
|
ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
mbedtls_md_free(&mbedtls_md_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
|
||||||
|
(void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
|
||||||
|
(void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
|
||||||
|
|
||||||
|
// <transfer the hash code to the string mode
|
||||||
|
ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iot_log.h>
|
||||||
|
|
||||||
|
static EnIotLogLevel gIoTLogLevel = EN_IOT_LOG_LEVEL_TRACE;
|
||||||
|
static const char *gIoTLogLevelNames[] = {
|
||||||
|
"TRACE",
|
||||||
|
"DEBUG",
|
||||||
|
"INFO ",
|
||||||
|
"WARN ",
|
||||||
|
"ERROR",
|
||||||
|
"FATAL"
|
||||||
|
};
|
||||||
|
|
||||||
|
int IoTLogLevelSet(EnIotLogLevel level)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
if (level < EN_IOT_LOG_LEVEL_MAX) {
|
||||||
|
gIoTLogLevel = level;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnIotLogLevel IoTLogLevelGet(void)
|
||||||
|
{
|
||||||
|
return gIoTLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *IoTLogLevelGetName(EnIotLogLevel logLevel)
|
||||||
|
{
|
||||||
|
if (logLevel >= EN_IOT_LOG_LEVEL_MAX) {
|
||||||
|
return "NULL ";
|
||||||
|
} else {
|
||||||
|
return gIoTLogLevelNames[logLevel];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_LOG_H_
|
||||||
|
#define IOT_LOG_H_
|
||||||
|
/**
|
||||||
|
* @brief:this defines for the log module,
|
||||||
|
* and IOT_LOG_TRACE/IOT_LOG_DEBUG will not participate the compile in the release version
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
typedef enum {
|
||||||
|
// < this is used as the trace function,like the function enter and function out
|
||||||
|
EN_IOT_LOG_LEVEL_TRACE = 0,
|
||||||
|
// < this is used as the debug, you could add any debug as you wish
|
||||||
|
EN_IOT_LOG_LEVEL_DEBUG,
|
||||||
|
// < which means it is import message, and you should known
|
||||||
|
EN_IOT_LOG_LEVEL_INFO,
|
||||||
|
// < this is used as the executed result,which means the status is not what we expected
|
||||||
|
EN_IOT_LOG_LEVEL_WARN,
|
||||||
|
// < this is used as the executed result,which means the status is not what we expected
|
||||||
|
EN_IOT_LOG_LEVEL_ERROR,
|
||||||
|
// < this is used as the parameters input for the api interface, which could not accepted
|
||||||
|
EN_IOT_LOG_LEVEL_FATAL,
|
||||||
|
EN_IOT_LOG_LEVEL_MAX,
|
||||||
|
}EnIotLogLevel;
|
||||||
|
/**
|
||||||
|
* @brief:use this function to get the current output log
|
||||||
|
*
|
||||||
|
* @return: the current output mask log, defined by en_iot_log_level_t
|
||||||
|
* */
|
||||||
|
EnIotLogLevel IoTLogLevelGet(void);
|
||||||
|
/**
|
||||||
|
* @brief: use this function to get the debug level name
|
||||||
|
*
|
||||||
|
* @parameter[in]:level, the level to get
|
||||||
|
*
|
||||||
|
* @return: the mapped level name
|
||||||
|
* */
|
||||||
|
const char *IoTLogLevelGetName(EnIotLogLevel logLevel);
|
||||||
|
/**
|
||||||
|
* @brief:use this function to set the current output log
|
||||||
|
*
|
||||||
|
* @parameter[in] level:defined by en_iot_log_level_t
|
||||||
|
*
|
||||||
|
* @return: 0 success while -1 failed
|
||||||
|
* */
|
||||||
|
int IoTLogLevelSet(EnIotLogLevel level);
|
||||||
|
/*
|
||||||
|
* @brief: this is a weak function ,and you could rewrite one
|
||||||
|
*
|
||||||
|
* @param fmt: same use as the fmt for printf
|
||||||
|
*
|
||||||
|
* @param unfixed: same use for printf
|
||||||
|
*
|
||||||
|
* @return: don't care about it
|
||||||
|
*
|
||||||
|
* @attention: and the components should not call this function directly, you'd better
|
||||||
|
*
|
||||||
|
* call IOT_LOG groups
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
#ifndef IOT_PRINT
|
||||||
|
#define IOT_PRINT(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
printf(fmt, ##__VA_ARGS__); \
|
||||||
|
}while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINKLOG_ENABLE
|
||||||
|
|
||||||
|
#define IOT_LOG(level, fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
IOT_PRINT("[%s][%s] " fmt "\r\n", \
|
||||||
|
IoTLogLevelGetName((level)), __FUNCTION__, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if ((EN_IOT_LOG_LEVEL_TRACE) >= IoTLogLevelGet()) \
|
||||||
|
{ \
|
||||||
|
IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define IOT_LOG_DEBUG(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if ((EN_IOT_LOG_LEVEL_DEBUG) >= IoTLogLevelGet()) \
|
||||||
|
{ \
|
||||||
|
IOT_LOG(EN_IOT_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define IOT_LOG(level, fmt, ...)
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...)
|
||||||
|
#define IOT_LOG_DEBUG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_INFO(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_WARN(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_ERROR(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_FATAL(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* IOT_LOG_H_ */
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_MAIN_H
|
||||||
|
#define IOT_MAIN_H
|
||||||
|
|
||||||
|
typedef void (*fnMsgCallBack)(int qos, const char *topic, const char *payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the iot main function. Please call this function first
|
||||||
|
*/
|
||||||
|
int IoTMain(void);
|
||||||
|
/**
|
||||||
|
* Use this function to set the message call back function, when some messages comes,
|
||||||
|
* the callback will be called, if you don't care about the message, set it to NULL
|
||||||
|
*/
|
||||||
|
int IoTSetMsgCallback(fnMsgCallBack msgCallback);
|
||||||
|
/**
|
||||||
|
* When you want to send some messages to the iot server(including the response message),
|
||||||
|
* please call this api
|
||||||
|
* @param qos: the mqtt qos,:0,1,2
|
||||||
|
* @param topic: the iot mqtt topic
|
||||||
|
* @param payload: the mqtt payload
|
||||||
|
*
|
||||||
|
* @return 0 success while others failed
|
||||||
|
*
|
||||||
|
* @instruction: if success means we write the message to the queue susccess,
|
||||||
|
* not means communicate with the server success
|
||||||
|
*/
|
||||||
|
int IotSendMsg(int qos, const char *topic, const char *payload);
|
||||||
|
|
||||||
|
#endif /* IOT_MAIN_H_ */
|
@ -0,0 +1,361 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_mem.h>
|
||||||
|
#include <cJSON.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "iot_main.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_profile.h"
|
||||||
|
|
||||||
|
// < format the report data to json string mode
|
||||||
|
static cJSON *FormateProflleValue(IoTProfileKV_t *kv)
|
||||||
|
{
|
||||||
|
cJSON *ret = NULL;
|
||||||
|
switch (kv->type) {
|
||||||
|
case EN_IOT_DATATYPE_INT:
|
||||||
|
ret = cJSON_CreateNumber(kv->iValue);
|
||||||
|
break;
|
||||||
|
case EN_IOT_DATATYPE_LONG:
|
||||||
|
ret = cJSON_CreateNumber((double)(*(long *)kv->value));
|
||||||
|
break;
|
||||||
|
case EN_IOT_DATATYPE_STRING:
|
||||||
|
ret = cJSON_CreateString((const char *)kv->value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON *MakeKvs(IoTProfileKV_t *kvlst)
|
||||||
|
{
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *kv;
|
||||||
|
IoTProfileKV_t *kvInfo;
|
||||||
|
|
||||||
|
// < build a root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
// < add all the property to the properties
|
||||||
|
kvInfo = kvlst;
|
||||||
|
while (kvInfo != NULL) {
|
||||||
|
kv = FormateProflleValue(kvInfo);
|
||||||
|
if (kv == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, kvInfo->key, kv);
|
||||||
|
kvInfo = kvInfo->nxt;
|
||||||
|
}
|
||||||
|
// < OK, now we return it
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_SERVICEID "service_id"
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_PROPERTIIES "properties"
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_EVENTTIME "event_time"
|
||||||
|
#define CN_PROFILE_KEY_SERVICES "services"
|
||||||
|
static cJSON *MakeService(IoTProfileService_t *serviceInfo)
|
||||||
|
{
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *serviceID;
|
||||||
|
cJSON *properties;
|
||||||
|
cJSON *eventTime;
|
||||||
|
|
||||||
|
// < build a root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
// < add the serviceID node to the root node
|
||||||
|
serviceID = cJSON_CreateString(serviceInfo->serviceID);
|
||||||
|
if (serviceID == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_SERVICEID, serviceID);
|
||||||
|
// < add the properties node to the root
|
||||||
|
properties = MakeKvs(serviceInfo->serviceProperty);
|
||||||
|
if (properties == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_PROPERTIIES, properties);
|
||||||
|
// < add the event time (optional) to the root
|
||||||
|
if (serviceInfo->eventTime != NULL) {
|
||||||
|
eventTime = cJSON_CreateString(serviceInfo->eventTime);
|
||||||
|
if (eventTime == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_EVENTTIME, eventTime);
|
||||||
|
}
|
||||||
|
// < OK, now we return it
|
||||||
|
cJSON_Delete(properties);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON *MakeServices(IoTProfileService_t *serviceInfo)
|
||||||
|
{
|
||||||
|
cJSON *services = NULL;
|
||||||
|
cJSON *service;
|
||||||
|
IoTProfileService_t *serviceTmp;
|
||||||
|
|
||||||
|
// < create the services array node
|
||||||
|
services = cJSON_CreateArray();
|
||||||
|
if (services == NULL) {
|
||||||
|
cJSON_Delete(services);
|
||||||
|
services = NULL;
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceTmp = serviceInfo;
|
||||||
|
while (serviceTmp != NULL) {
|
||||||
|
service = MakeService(serviceTmp);
|
||||||
|
if (service == NULL) {
|
||||||
|
if (services != NULL) {
|
||||||
|
cJSON_Delete(services);
|
||||||
|
services = NULL;
|
||||||
|
}
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToArray(services, service);
|
||||||
|
serviceTmp = serviceTmp->nxt;
|
||||||
|
}
|
||||||
|
// < now we return the services
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
// < use this function to make a topic to publish
|
||||||
|
// < if request_id is needed depends on the fmt
|
||||||
|
static char *MakeTopic(const char *fmt, const char *deviceID, const char *requestID)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
len = strlen(fmt) + strlen(deviceID);
|
||||||
|
if (requestID != NULL) {
|
||||||
|
len += strlen(requestID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hi_malloc(0, len);
|
||||||
|
if (ret != NULL) {
|
||||||
|
if (requestID != NULL) {
|
||||||
|
(void)snprintf_s(ret, len, len, fmt, deviceID, requestID);
|
||||||
|
} else {
|
||||||
|
(void)snprintf_s(ret, len, len, fmt, deviceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_RETCODE "result_code"
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_RESPNAME "response_name"
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_PARAS "paras"
|
||||||
|
static char *MakeProfileCmdResp(IoTCmdResp_t *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *retCode;
|
||||||
|
cJSON *respName;
|
||||||
|
cJSON *paras;
|
||||||
|
|
||||||
|
// < create the root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// < create retcode and retdesc and add it to the root
|
||||||
|
retCode = cJSON_CreateNumber(payload->retCode);
|
||||||
|
if (retCode == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RETCODE, retCode);
|
||||||
|
if (payload->respName != NULL) {
|
||||||
|
respName = cJSON_CreateString(payload->respName);
|
||||||
|
if (respName == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RESPNAME, respName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload->paras != NULL) {
|
||||||
|
paras = MakeKvs(payload->paras);
|
||||||
|
if (paras == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_PARAS, paras);
|
||||||
|
}
|
||||||
|
// < OK, now we make it to a buffer
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *MakeProfilePropertyReport(IoTProfileService_t *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *services;
|
||||||
|
|
||||||
|
// < create the root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// < create the services array node to the root
|
||||||
|
services = MakeServices(payload);
|
||||||
|
if (services == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_KEY_SERVICES, services);
|
||||||
|
// < OK, now we make it to a buffer
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WECHAT_SUBSCRIBE_TYPE "update"
|
||||||
|
#define WECHAT_SUBSCRIBE_VERSION "1.0.0"
|
||||||
|
#define WECHAT_SUBSCRIBE_TOKEN "DeviceSubscribe"
|
||||||
|
static char *MakeProfileReport(WeChatProfile *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *state;
|
||||||
|
cJSON *reported;
|
||||||
|
|
||||||
|
/* create json root node */
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* state create */
|
||||||
|
state = cJSON_CreateObject();
|
||||||
|
if (state == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* reported create */
|
||||||
|
reported = cJSON_CreateObject();
|
||||||
|
if (reported == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* add root object */
|
||||||
|
cJSON_AddItemToObject(root, payload->subscribeType, cJSON_CreateString(WECHAT_SUBSCRIBE_TYPE));
|
||||||
|
cJSON_AddItemToObject(root, payload->status.subState, state);
|
||||||
|
cJSON_AddItemToObject(state, payload->status.subReport, reported);
|
||||||
|
cJSON_AddItemToObject(root, payload->status.reportVersion, cJSON_CreateString(WECHAT_SUBSCRIBE_VERSION));
|
||||||
|
cJSON_AddItemToObject(root, payload->status.Token, cJSON_CreateString(WECHAT_SUBSCRIBE_TOKEN));
|
||||||
|
/* add reported item */
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLight,
|
||||||
|
payload->reportAction.lightActionStatus);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionMotor,
|
||||||
|
payload->reportAction.motorActionStatus);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionTemperature,
|
||||||
|
payload->reportAction.temperatureData);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionHumidity,
|
||||||
|
payload->reportAction.humidityActionData);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLightIntensity,
|
||||||
|
payload->reportAction.lightIntensityActionData);
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(state);
|
||||||
|
cJSON_Delete(reported);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_TOPICFMT_TOPIC "YT32IOSCAL/Hi38611_mqtt/event"
|
||||||
|
/*int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *topic;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
|
if ((deviceID == NULL) || (payload== NULL)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
|
||||||
|
if (topic == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg = MakeProfileReport(payload);
|
||||||
|
if ((topic != NULL) && (msg != NULL)) {
|
||||||
|
ret = IotSendMsg(0, topic, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
hi_free(0, topic);
|
||||||
|
cJSON_free(msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int IoTProfilePropertyReport_uart(char *deviceID, char *msg)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *topic;
|
||||||
|
//char *msg;
|
||||||
|
|
||||||
|
if ((deviceID == NULL) || (msg == NULL)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
|
||||||
|
if (topic == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//msg = MakeProfileReport(payload);
|
||||||
|
if ((topic != NULL) && (msg != NULL)) {
|
||||||
|
ret = IotSendMsg(0, topic, msg);
|
||||||
|
printf("send success\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
hi_free(0, topic);
|
||||||
|
//cJSON_free(msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_PROFILE_H
|
||||||
|
#define IOT_PROFILE_H
|
||||||
|
|
||||||
|
#include <hi_types_base.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
|
||||||
|
#define OC_BEEP_STATUS_ON ((hi_u8) 0x01)
|
||||||
|
#define OC_BEEP_STATUS_OFF ((hi_u8) 0x00)
|
||||||
|
|
||||||
|
// < enum all the data type for the oc profile
|
||||||
|
typedef enum {
|
||||||
|
EN_IOT_DATATYPE_INT = 0,
|
||||||
|
EN_IOT_DATATYPE_LONG,
|
||||||
|
EN_IOT_DATATYPE_FLOAT,
|
||||||
|
EN_IOT_DATATYPE_DOUBLE,
|
||||||
|
EN_IOT_DATATYPE_STRING, // < must be ended with '\0'
|
||||||
|
EN_IOT_DATATYPE_LAST,
|
||||||
|
}IoTDataType_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OC_LED_ON = 1,
|
||||||
|
OC_LED_OFF
|
||||||
|
}OcLedValue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *nxt; // < ponit to the next key
|
||||||
|
const char *key;
|
||||||
|
const char *value;
|
||||||
|
hi_u32 iValue;
|
||||||
|
IoTDataType_t type;
|
||||||
|
}IoTProfileKV_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *nxt;
|
||||||
|
char *serviceID;
|
||||||
|
char *eventTime;
|
||||||
|
IoTProfileKV_t *serviceProperty;
|
||||||
|
}IoTProfileService_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int retCode; // < response code, 0 success while others failed
|
||||||
|
const char *respName; // < response name
|
||||||
|
const char *requestID; // < specified by the message command
|
||||||
|
IoTProfileKV_t *paras; // < the command paras
|
||||||
|
}IoTCmdResp_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *subState;
|
||||||
|
const char *subReport;
|
||||||
|
const char *reportVersion;
|
||||||
|
const char *Token;
|
||||||
|
}WeChatProfileStatus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int lightActionStatus;
|
||||||
|
int motorActionStatus;
|
||||||
|
int temperatureData;
|
||||||
|
int humidityActionData;
|
||||||
|
int lightIntensityActionData;
|
||||||
|
const char *subDeviceActionLight;
|
||||||
|
const char *subDeviceActionMotor;
|
||||||
|
const char *subDeviceActionTemperature;
|
||||||
|
const char *subDeviceActionHumidity;
|
||||||
|
const char *subDeviceActionLightIntensity;
|
||||||
|
}WeChatProfileReporte;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *subscribeType;
|
||||||
|
WeChatProfileStatus status;
|
||||||
|
WeChatProfileReporte reportAction;
|
||||||
|
}WeChatProfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use this function to report the property to the iot platform
|
||||||
|
*/
|
||||||
|
//int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload);
|
||||||
|
int IoTProfilePropertyReport_uart(char *deviceID, char *msg);
|
||||||
|
void cJsonInit(void);
|
||||||
|
void WifiStaReadyWait(void);
|
||||||
|
#endif
|
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// < this demo make the wifi to connect to the specified AP
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <hi_wifi_api.h>
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
#include <lwip/netifapi.h>
|
||||||
|
#include <hi_types_base.h>
|
||||||
|
#include <hi_task.h>
|
||||||
|
#include <hi_mem.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "wifi_device.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "wifi_device_config.h"
|
||||||
|
#include "lwip/api_shell.h"
|
||||||
|
|
||||||
|
#define APP_INIT_VAP_NUM 2
|
||||||
|
#define APP_INIT_USR_NUM 2
|
||||||
|
|
||||||
|
static struct netif *gLwipNetif = NULL;
|
||||||
|
static hi_bool gScanDone = HI_FALSE;
|
||||||
|
unsigned char wifiStatus = 0;
|
||||||
|
|
||||||
|
unsigned char wifiFirstConnecting = 0;
|
||||||
|
unsigned char wifiSecondConnecting = 0;
|
||||||
|
unsigned char wifiSecondConnected = 0;
|
||||||
|
static struct netif* g_iface = NULL;
|
||||||
|
void WifiStopSta(int netId);
|
||||||
|
static int WifiStartSta(void);
|
||||||
|
int cnetId = -1;
|
||||||
|
int g_connected = 0;
|
||||||
|
|
||||||
|
#define WIFI_CONNECT_STATUS ((unsigned char)0x02)
|
||||||
|
|
||||||
|
void wifiReconnected(int netId)
|
||||||
|
{
|
||||||
|
int recnetId = netId;
|
||||||
|
if (wifiFirstConnecting == WIFI_CONNECT_STATUS) {
|
||||||
|
wifiSecondConnecting = HI_TRUE;
|
||||||
|
wifiFirstConnecting = HI_FALSE;
|
||||||
|
WifiStopSta(recnetId);
|
||||||
|
ip4_addr_t ipAddr;
|
||||||
|
ip4_addr_t ipAny;
|
||||||
|
IP4_ADDR(&ipAny, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
|
||||||
|
recnetId = WifiStartSta();
|
||||||
|
netifapi_dhcp_start(gLwipNetif);
|
||||||
|
while (0 == memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t))) {
|
||||||
|
IOT_LOG_DEBUG("<Wifi reconnecting>:Wait the DHCP READY");
|
||||||
|
netifapi_netif_get_addr(gLwipNetif, &ipAddr, NULL, NULL);
|
||||||
|
hi_sleep(1000); /* 1000: cpu sleep 1000 ms */
|
||||||
|
}
|
||||||
|
wifiSecondConnected = HI_FALSE;
|
||||||
|
wifiFirstConnecting = WIFI_CONNECT_STATUS;
|
||||||
|
wifiStatus = HI_WIFI_EVT_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* clear netif's ip, gateway and netmask */
|
||||||
|
static void StaResetAddr(struct netif *lwipNetif)
|
||||||
|
{
|
||||||
|
ip4_addr_t st_gw;
|
||||||
|
ip4_addr_t st_ipaddr;
|
||||||
|
ip4_addr_t st_netmask;
|
||||||
|
|
||||||
|
if (lwipNetif == NULL) {
|
||||||
|
IOT_LOG_ERROR("hisi_reset_addr::Null param of netdev");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IP4_ADDR(&st_gw, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&st_netmask, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
netifapi_netif_set_addr(lwipNetif, &st_ipaddr, &st_netmask, &st_gw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WpaEventCB(const hi_wifi_event *hisiEvent)
|
||||||
|
{
|
||||||
|
if (hisiEvent == NULL)
|
||||||
|
return;
|
||||||
|
IOT_LOG_DEBUG("EVENT_TYPE:%d", hisiEvent->event);
|
||||||
|
switch (hisiEvent->event) {
|
||||||
|
case HI_WIFI_EVT_SCAN_DONE:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Scan results available");
|
||||||
|
gScanDone = HI_TRUE;
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_CONNECTED:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Connected");
|
||||||
|
netifapi_dhcp_start(gLwipNetif);
|
||||||
|
wifiStatus = HI_WIFI_EVT_CONNECTED;
|
||||||
|
if (wifiSecondConnected) {
|
||||||
|
wifiSecondConnected = HI_FALSE;
|
||||||
|
wifiFirstConnecting = WIFI_CONNECT_STATUS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_DISCONNECTED:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Disconnected");
|
||||||
|
netifapi_dhcp_stop(gLwipNetif);
|
||||||
|
StaResetAddr(gLwipNetif);
|
||||||
|
wifiStatus = HI_WIFI_EVT_DISCONNECTED;
|
||||||
|
wifiReconnected(cnetId);
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_WPS_TIMEOUT:
|
||||||
|
IOT_LOG_DEBUG("WiFi: wps is timeout");
|
||||||
|
wifiStatus = HI_WIFI_EVT_WPS_TIMEOUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int StaStartConnect(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
errno_t rc;
|
||||||
|
hi_wifi_assoc_request assoc_req = {0};
|
||||||
|
|
||||||
|
/* copy SSID to assoc_req */
|
||||||
|
rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, CONFIG_AP_SSID, strlen(CONFIG_AP_SSID));
|
||||||
|
if (rc != EOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OPEN mode
|
||||||
|
* for WPA2-PSK mode:
|
||||||
|
* set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
|
||||||
|
* then memcpy(assoc_req.key, "12345678", 8).
|
||||||
|
*/
|
||||||
|
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
|
||||||
|
rc = memcpy_s(assoc_req.key, HI_WIFI_MAX_KEY_LEN + 1, CONFIG_AP_PWD, strlen(CONFIG_AP_PWD));
|
||||||
|
if (rc != EOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hi_wifi_sta_connect(&assoc_req);
|
||||||
|
if (ret != HISI_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintLinkedInfo(WifiLinkedInfo* info)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char macAddress[32] = {0};
|
||||||
|
unsigned char* mac = info->bssid;
|
||||||
|
if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
|
||||||
|
{
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
|
||||||
|
PrintLinkedInfo(info);
|
||||||
|
|
||||||
|
if (state == WIFI_STATE_AVALIABLE) {
|
||||||
|
g_connected = 1;
|
||||||
|
} else {
|
||||||
|
g_connected = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnWifiScanStateChanged(int state, int size)
|
||||||
|
{
|
||||||
|
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WifiEvent g_defaultWifiEventListener = {
|
||||||
|
.OnWifiConnectionChanged = OnWifiConnectionChanged,
|
||||||
|
.OnWifiScanStateChanged = OnWifiScanStateChanged
|
||||||
|
};
|
||||||
|
|
||||||
|
static int WifiStartSta(void)
|
||||||
|
{
|
||||||
|
WifiDeviceConfig apConfig = {0};
|
||||||
|
strcpy_s(apConfig.ssid, sizeof(CONFIG_AP_SSID), CONFIG_AP_SSID);
|
||||||
|
strcpy_s(apConfig.preSharedKey, sizeof(CONFIG_AP_PWD), CONFIG_AP_PWD);
|
||||||
|
apConfig.securityType = WIFI_SEC_TYPE_PSK;
|
||||||
|
|
||||||
|
WifiErrorCode errCode;
|
||||||
|
int netId = -1;
|
||||||
|
|
||||||
|
errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
|
||||||
|
printf("RegisterWifiEvent: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = EnableWifi();
|
||||||
|
printf("EnableWifi: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = AddDeviceConfig(&apConfig, &netId);
|
||||||
|
printf("AddDeviceConfig: %d\r\n", errCode);
|
||||||
|
|
||||||
|
g_connected = 0;
|
||||||
|
errCode = ConnectTo(netId);
|
||||||
|
printf("ConnectTo(%d): %d\r\n", netId, errCode);
|
||||||
|
|
||||||
|
while (!g_connected) { // wait until connect to AP
|
||||||
|
osDelay(10); /* 10: os sleep 10ms */
|
||||||
|
}
|
||||||
|
printf("g_connected: %d\r\n", g_connected);
|
||||||
|
|
||||||
|
g_iface = netifapi_netif_find("wlan0");
|
||||||
|
if (g_iface) {
|
||||||
|
err_t ret = netifapi_dhcp_start(g_iface);
|
||||||
|
printf("netifapi_dhcp_start: %d\r\n", ret);
|
||||||
|
|
||||||
|
osDelay(100); // 100: os sleep 100ms wait DHCP server give me IP
|
||||||
|
ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
|
||||||
|
printf("netifapi_netif_common: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiStopSta(int netId)
|
||||||
|
{
|
||||||
|
int stopNetId = netId;
|
||||||
|
|
||||||
|
if (g_iface) {
|
||||||
|
err_t ret = netifapi_dhcp_stop(g_iface);
|
||||||
|
printf("netifapi_dhcp_stop: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiErrorCode errCode = Disconnect(); // disconnect with your AP
|
||||||
|
printf("Disconnect: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
|
||||||
|
printf("UnRegisterWifiEvent: %d\r\n", errCode);
|
||||||
|
|
||||||
|
RemoveDevice(stopNetId); // remove AP config
|
||||||
|
printf("RemoveDevice: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = DisableWifi();
|
||||||
|
printf("DisableWifi: %d\r\n", errCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiStaReadyWait(void)
|
||||||
|
{
|
||||||
|
ip4_addr_t ipAddr;
|
||||||
|
ip4_addr_t ipAny;
|
||||||
|
IP4_ADDR(&ipAny, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
|
||||||
|
cnetId = WifiStartSta();
|
||||||
|
IOT_LOG_DEBUG("wifi sta dhcp done");
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
static_library("interconnectionClient") {
|
||||||
|
sources = [
|
||||||
|
"app_demo_uart.c",
|
||||||
|
"hal_iot_gpio_ex.c",
|
||||||
|
"hisignalling_protocol.c",
|
||||||
|
]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"./",
|
||||||
|
"//utils/native/lite/include",
|
||||||
|
"//kernel/liteos_m/kal/cmsis",
|
||||||
|
"//base/iot_hardware/peripheral/interfaces/kits",
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_stdlib.h>
|
||||||
|
#include <hisignalling_protocol.h>
|
||||||
|
#include <hi_uart.h>
|
||||||
|
#include <app_demo_uart.h>
|
||||||
|
#include <iot_uart.h>
|
||||||
|
#include <hi_gpio.h>
|
||||||
|
#include <hi_io.h>
|
||||||
|
#include "iot_gpio_ex.h"
|
||||||
|
#include "ohos_init.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
UartDefConfig uartDefConfig = {0};
|
||||||
|
|
||||||
|
static void Uart1GpioCOnfig(void)
|
||||||
|
{
|
||||||
|
#ifdef ROBOT_BOARD
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_5, IOT_IO_FUNC_GPIO_5_UART1_RXD);
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_6, IOT_IO_FUNC_GPIO_6_UART1_TXD);
|
||||||
|
/* IOT_BOARD */
|
||||||
|
#elif defined (EXPANSION_BOARD)
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_0, IOT_IO_FUNC_GPIO_0_UART1_TXD);
|
||||||
|
IoSetFunc(HI_IO_NAME_GPIO_1, IOT_IO_FUNC_GPIO_1_UART1_RXD);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int SetUartRecvFlag(UartRecvDef def)
|
||||||
|
{
|
||||||
|
if (def == UART_RECV_TRUE) {
|
||||||
|
uartDefConfig.g_uartReceiveFlag = HI_TRUE;
|
||||||
|
} else {
|
||||||
|
uartDefConfig.g_uartReceiveFlag = HI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uartDefConfig.g_uartReceiveFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetUartConfig(UartDefType type)
|
||||||
|
{
|
||||||
|
int receive = 0;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case UART_RECEIVE_FLAG:
|
||||||
|
receive = uartDefConfig.g_uartReceiveFlag;
|
||||||
|
break;
|
||||||
|
case UART_RECVIVE_LEN:
|
||||||
|
receive = uartDefConfig.g_uartLen;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return receive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetUartReceiveMsg(void)
|
||||||
|
{
|
||||||
|
(void)memset_s(uartDefConfig.g_receiveUartBuff, sizeof(uartDefConfig.g_receiveUartBuff),
|
||||||
|
0x0, sizeof(uartDefConfig.g_receiveUartBuff));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *GetUartReceiveMsg(void)
|
||||||
|
{
|
||||||
|
return uartDefConfig.g_receiveUartBuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hi_void *UartDemoTask(char *param)
|
||||||
|
{
|
||||||
|
hi_u8 uartBuff[UART_BUFF_SIZE] = {0};
|
||||||
|
hi_unref_param(param);
|
||||||
|
printf("Initialize uart demo successfully, please enter some datas via DEMO_UART_NUM port...\n");
|
||||||
|
Uart1GpioCOnfig();
|
||||||
|
for (;;) {
|
||||||
|
uartDefConfig.g_uartLen = IoTUartRead(DEMO_UART_NUM, uartBuff, UART_BUFF_SIZE);
|
||||||
|
if ((uartDefConfig.g_uartLen > 0) && (uartBuff[0] == 0xaa) && (uartBuff[1] == 0x55)) {
|
||||||
|
if (GetUartConfig(UART_RECEIVE_FLAG) == HI_FALSE) {
|
||||||
|
(void)memcpy_s(uartDefConfig.g_receiveUartBuff, uartDefConfig.g_uartLen,
|
||||||
|
uartBuff, uartDefConfig.g_uartLen);/*uartBuff中的信息放到uartDefConfig.g_receiveUartBuff*/
|
||||||
|
(void)SetUartRecvFlag(UART_RECV_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("len:%d\n", uartDefConfig.g_uartLen);
|
||||||
|
|
||||||
|
for (int i = 0; i<uartDefConfig.g_uartLen; i++)
|
||||||
|
{
|
||||||
|
if(i <= 2)
|
||||||
|
{
|
||||||
|
printf("0x%x ", uartBuff[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("%c ", uartBuff[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskMsleep(20); /* 20:sleep 20ms */
|
||||||
|
}
|
||||||
|
return HI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This demo simply shows how to read datas from UART2 port and then echo back.
|
||||||
|
*/
|
||||||
|
hi_void UartTransmit(hi_void)
|
||||||
|
{
|
||||||
|
hi_u32 ret = 0;
|
||||||
|
|
||||||
|
IotUartAttribute uartAttr = {
|
||||||
|
.baudRate = 115200, /* baudRate: 115200 */
|
||||||
|
.dataBits = 8, /* dataBits: 8bits */
|
||||||
|
.stopBits = 1, /* stop bit */
|
||||||
|
.parity = 0,
|
||||||
|
};
|
||||||
|
/* Initialize uart driver */
|
||||||
|
ret = IoTUartInit(DEMO_UART_NUM, &uartAttr);
|
||||||
|
if (ret != HI_ERR_SUCCESS) {
|
||||||
|
printf("Failed to init uart! Err code = %d\n", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Create a task to handle uart communication */
|
||||||
|
osThreadAttr_t attr = {0};
|
||||||
|
attr.stack_size = UART_DEMO_TASK_STAK_SIZE;
|
||||||
|
attr.priority = UART_DEMO_TASK_PRIORITY;
|
||||||
|
attr.name = (hi_char*)"uart demo";
|
||||||
|
if (osThreadNew((osThreadFunc_t)UartDemoTask, NULL, &attr) == NULL) {
|
||||||
|
printf("Falied to create uart demo task!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SYS_RUN(UartTransmit);
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APP_DEMO_UART_H
|
||||||
|
#define APP_DEMO_UART_H
|
||||||
|
|
||||||
|
#define UART_BUFF_SIZE 1024
|
||||||
|
#define WRITE_BY_INT
|
||||||
|
#define UART_DEMO_TASK_STAK_SIZE 2048
|
||||||
|
#define UART_DEMO_TASK_PRIORITY 25
|
||||||
|
#define DEMO_UART_NUM HI_UART_IDX_1
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_RECEIVE_FLAG = 0,
|
||||||
|
UART_RECVIVE_LEN,
|
||||||
|
UART_SEND_FLAG = 2,
|
||||||
|
UART_SEND_LEN
|
||||||
|
}UartDefType;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_RECV_TRUE = 0,
|
||||||
|
UART_RECV_FALSE,
|
||||||
|
}UartRecvDef;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int uartChannel;
|
||||||
|
unsigned char g_receiveUartBuff[UART_BUFF_SIZE];
|
||||||
|
int g_uartReceiveFlag;
|
||||||
|
int g_uartLen;
|
||||||
|
}UartDefConfig;
|
||||||
|
|
||||||
|
int SetUartRecvFlag(UartRecvDef def);
|
||||||
|
int GetUartConfig(UartDefType type);
|
||||||
|
void ResetUartReceiveMsg(void);
|
||||||
|
unsigned char *GetUartReceiveMsg(void);
|
||||||
|
#endif
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "iot_errno.h"
|
||||||
|
#include "hi_gpio.h"
|
||||||
|
#include "hi_io.h"
|
||||||
|
#include "hi_task.h"
|
||||||
|
#include "hi_types_base.h"
|
||||||
|
#include "iot_gpio_ex.h"
|
||||||
|
|
||||||
|
unsigned int IoSetPull(unsigned int id, IotIoPull val)
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int IoSetFunc(unsigned int id, unsigned char val) /* 复用功能 */
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_func((hi_io_name)id, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
# Copyright (c) 2020-2022 Huawei Device Co., Ltd.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
static_library("led_example") {
|
||||||
|
sources = [ "led_example.c" ]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"//utils/native/lite/include",
|
||||||
|
"//kernel/liteos_m/kal/cmsis",
|
||||||
|
"//base/iot_hardware/peripheral/interfaces/kits",
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2022 Huawei Device Co., Ltd.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "ohos_init.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "iot_gpio.h"
|
||||||
|
|
||||||
|
#define LED_INTERVAL_TIME_US 300000
|
||||||
|
#define LED_TASK_STACK_SIZE 512
|
||||||
|
#define LED_TASK_PRIO 25
|
||||||
|
#define LED_TEST_GPIO 9 // for hispark_pegasus
|
||||||
|
|
||||||
|
enum LedState {
|
||||||
|
LED_ON = 0,
|
||||||
|
LED_OFF,
|
||||||
|
LED_SPARK,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LedState g_ledState = LED_SPARK;
|
||||||
|
|
||||||
|
static void *LedTask(const char *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
while (1) {
|
||||||
|
switch (g_ledState) {
|
||||||
|
case LED_ON:
|
||||||
|
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
|
||||||
|
usleep(LED_INTERVAL_TIME_US);
|
||||||
|
break;
|
||||||
|
case LED_OFF:
|
||||||
|
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
|
||||||
|
usleep(LED_INTERVAL_TIME_US);
|
||||||
|
break;
|
||||||
|
case LED_SPARK:
|
||||||
|
IoTGpioSetOutputVal(LED_TEST_GPIO, 0);
|
||||||
|
usleep(LED_INTERVAL_TIME_US);
|
||||||
|
IoTGpioSetOutputVal(LED_TEST_GPIO, 1);
|
||||||
|
usleep(LED_INTERVAL_TIME_US);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usleep(LED_INTERVAL_TIME_US);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void LedExampleEntry(void)
|
||||||
|
{
|
||||||
|
osThreadAttr_t attr;
|
||||||
|
|
||||||
|
IoTGpioInit(LED_TEST_GPIO);
|
||||||
|
IoTGpioSetDir(LED_TEST_GPIO, IOT_GPIO_DIR_OUT);
|
||||||
|
|
||||||
|
attr.name = "LedTask";
|
||||||
|
attr.attr_bits = 0U;
|
||||||
|
attr.cb_mem = NULL;
|
||||||
|
attr.cb_size = 0U;
|
||||||
|
attr.stack_mem = NULL;
|
||||||
|
attr.stack_size = LED_TASK_STACK_SIZE;
|
||||||
|
attr.priority = LED_TASK_PRIO;
|
||||||
|
|
||||||
|
if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) {
|
||||||
|
printf("[LedExample] Failed to create LedTask!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_RUN(LedExampleEntry);
|
@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
static_library("AppDemoIot") {
|
||||||
|
sources = [
|
||||||
|
"app_demo_iot.c",
|
||||||
|
"cjson_init.c",
|
||||||
|
"iot_hmac.c",
|
||||||
|
"iot_log.c",
|
||||||
|
"iot_main.c",
|
||||||
|
"iot_profile.c",
|
||||||
|
"iot_sta.c",
|
||||||
|
"hal_iot_gpio_ex.c",
|
||||||
|
]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"./",
|
||||||
|
"//utils/native/lite/include",
|
||||||
|
"//kernel/liteos_m/kal/cmsis",
|
||||||
|
"//base/iot_hardware/peripheral/interfaces/kits",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
|
||||||
|
"//third_party/cJSON",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
|
||||||
|
"//foundation/communication/wifi_lite/interfaces/wifiservice",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [ "WITH_LWIP" ]
|
||||||
|
}
|
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_task.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <hi_wifi_api.h>
|
||||||
|
#include <hi_mux.h>
|
||||||
|
#include <hi_io.h>
|
||||||
|
#include <hi_gpio.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "iot_main.h"
|
||||||
|
#include "iot_profile.h"
|
||||||
|
#include "ohos_init.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "iot_gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* attribute initiative to report */
|
||||||
|
#define TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
#define TWO_SECOND (2000)
|
||||||
|
/* oc request id */
|
||||||
|
#define CN_COMMADN_INDEX "commands/request_id="
|
||||||
|
#define WECHAT_SUBSCRIBE_control "chosen_slot"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel1 "slot_1"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel2 "slot_2"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel3 "slot_3"
|
||||||
|
#define WECHAT_SUBSCRIBE_channel4 "slot_4"
|
||||||
|
#define topic_data "YT32IOSCAL/Hi38611_mqtt/data"
|
||||||
|
#define topic_event "YT32IOSCAL/Hi38611_mqtt/event"
|
||||||
|
#define topic_control "YT32IOSCAL/Hi38611_mqtt/control"
|
||||||
|
|
||||||
|
int g_ligthStatus = -1;
|
||||||
|
int slot1 = 20,slot2 = 20, slot3 = 20, slot4 = 20;
|
||||||
|
typedef void (*FnMsgCallBack)(hi_gpio_value val);
|
||||||
|
|
||||||
|
typedef struct FunctionCallback {
|
||||||
|
hi_bool stop;
|
||||||
|
hi_u32 conLost;
|
||||||
|
hi_u32 queueID;
|
||||||
|
hi_u32 iotTaskID;
|
||||||
|
FnMsgCallBack msgCallBack;
|
||||||
|
}FunctionCallback;
|
||||||
|
FunctionCallback g_functinoCallback;
|
||||||
|
|
||||||
|
/* CPU Sleep time Set */
|
||||||
|
unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return HI_ERR_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeviceConfigInit(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
|
||||||
|
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
|
||||||
|
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_control(unsigned int IO){
|
||||||
|
IoTGpioInit(IO);
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u started!", IO);
|
||||||
|
hi_udelay(20000);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_start(unsigned int IO){
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE1);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u started!", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_stop(unsigned int IO){
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u stopped!", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void engine_reinit(unsigned int IO){
|
||||||
|
IoTGpioInit(IO);
|
||||||
|
IoSetFunc(IO, 0);
|
||||||
|
IoTGpioSetDir(IO, IOT_GPIO_DIR_OUT);
|
||||||
|
IoTGpioSetOutputVal(IO, IOT_GPIO_VALUE0);
|
||||||
|
IOT_LOG_DEBUG("Engine at GPIO:%u initialized!", IO);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void all_engine_reinit(){
|
||||||
|
engine_reinit(6);
|
||||||
|
engine_reinit(7);
|
||||||
|
engine_reinit(9);
|
||||||
|
engine_reinit(10);
|
||||||
|
IOT_LOG_DEBUG("All engines initialized!");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
|
||||||
|
{
|
||||||
|
g_functinoCallback.msgCallBack = msgCallBack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wechatControlDeviceMsg(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
DeviceConfigInit(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
|
||||||
|
// < The payload here is the json string
|
||||||
|
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)/*定义3861接收到json文件后的操作*/
|
||||||
|
{
|
||||||
|
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
|
||||||
|
int IO = 0;
|
||||||
|
/* 云端下发命令后,板端的操作处理 */
|
||||||
|
//if (strcmp(topic, topic_data)==0){
|
||||||
|
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_control) != NULL) {
|
||||||
|
all_engine_reinit();
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_channel1) != NULL) {
|
||||||
|
engine_start(6);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(6);
|
||||||
|
slot1--;
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel2) != NULL) {
|
||||||
|
engine_start(7);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(7);
|
||||||
|
slot2--;
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel3) != NULL) {
|
||||||
|
engine_start(2);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(2);
|
||||||
|
slot3--;
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
}
|
||||||
|
else if (strstr(payload, WECHAT_SUBSCRIBE_channel4) != NULL) {
|
||||||
|
engine_start(10);
|
||||||
|
hi_udelay(4000000);
|
||||||
|
engine_stop(10);
|
||||||
|
slot4--;
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
return HI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* publish sample */
|
||||||
|
hi_void IotPublishSample(int slot1, int slot2, int slot3, int slot4)
|
||||||
|
{
|
||||||
|
/* reported attribute */
|
||||||
|
WeChatProfile weChatProfile = {
|
||||||
|
.subscribeType = "type",
|
||||||
|
.status.subState = "state",
|
||||||
|
.status.subReport = "reported",
|
||||||
|
.status.reportVersion = "version",
|
||||||
|
.status.Token = "clientToken",
|
||||||
|
/* report motor */
|
||||||
|
.reportAction.subDeviceActionMotor = "slot_1",
|
||||||
|
.reportAction.motorActionStatus = slot1, /* 0 : motor off */
|
||||||
|
/* report temperature */
|
||||||
|
.reportAction.subDeviceActionTemperature = "slot_2",
|
||||||
|
.reportAction.temperatureData = slot2, /* 30 :temperature data */
|
||||||
|
/* report humidity */
|
||||||
|
.reportAction.subDeviceActionHumidity = "slot_3",
|
||||||
|
.reportAction.humidityActionData = slot3, /* humidity data */
|
||||||
|
/* report light_intensity */
|
||||||
|
.reportAction.subDeviceActionLightIntensity = "slot_4",
|
||||||
|
.reportAction.lightIntensityActionData = slot4, /* 60 : light_intensity */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* report light */
|
||||||
|
if (g_ligthStatus == HI_TRUE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 1; /* 1: light on */
|
||||||
|
} else if (g_ligthStatus == HI_FALSE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
|
||||||
|
} else {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
|
||||||
|
}
|
||||||
|
/* profile report */
|
||||||
|
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
|
||||||
|
// < wait if any work to do in the while
|
||||||
|
static hi_void *DemoEntry(const char *arg)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
WifiStaReadyWait();
|
||||||
|
cJsonInit();
|
||||||
|
IoTMain();
|
||||||
|
/* 云端下发回调 */
|
||||||
|
IoTSetMsgCallback(DemoMsgRcvCallBack);
|
||||||
|
|
||||||
|
/* 主动上报 */
|
||||||
|
#ifdef TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
while (1) {
|
||||||
|
/* 用户可以在这调用发布函数进行发布,需要用户自己写调用函数 */
|
||||||
|
IotPublishSample(slot1,slot2,slot3,slot4); // 发布例程
|
||||||
|
#endif
|
||||||
|
TaskMsleep(TWO_SECOND);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// < This is the demo entry, we create a task here,
|
||||||
|
// and all the works has been done in the demo_entry
|
||||||
|
#define CN_IOT_TASK_STACKSIZE 0x1000
|
||||||
|
#define CN_IOT_TASK_PRIOR 25
|
||||||
|
#define CN_IOT_TASK_NAME "IOTDEMO"
|
||||||
|
|
||||||
|
static void AppDemoIot(void)
|
||||||
|
{
|
||||||
|
osThreadAttr_t attr;
|
||||||
|
IoTWatchDogDisable();
|
||||||
|
|
||||||
|
attr.name = "IOTDEMO";
|
||||||
|
attr.attr_bits = 0U;
|
||||||
|
attr.cb_mem = NULL;
|
||||||
|
attr.cb_size = 0U;
|
||||||
|
attr.stack_mem = NULL;
|
||||||
|
attr.stack_size = CN_IOT_TASK_STACKSIZE;
|
||||||
|
attr.priority = CN_IOT_TASK_PRIOR;
|
||||||
|
|
||||||
|
if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
|
||||||
|
printf("[mqtt] Falied to create IOTDEMO!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_RUN(AppDemoIot);
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cJSON.h>
|
||||||
|
#include <hi_mem.h>
|
||||||
|
|
||||||
|
static void *cJsonMalloc(size_t sz)
|
||||||
|
{
|
||||||
|
return hi_malloc(0, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cJsonFree(const char *p)
|
||||||
|
{
|
||||||
|
hi_free(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cJsonInit(void)
|
||||||
|
{
|
||||||
|
cJSON_Hooks hooks;
|
||||||
|
hooks.malloc_fn = cJsonMalloc;
|
||||||
|
hooks.free_fn = cJsonFree;
|
||||||
|
cJSON_InitHooks(&hooks);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "iot_errno.h"
|
||||||
|
#include "iot_gpio_ex.h"
|
||||||
|
#include "hi_gpio.h"
|
||||||
|
#include "hi_io.h"
|
||||||
|
#include "hi_task.h"
|
||||||
|
#include "hi_types_base.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int IoSetPull(unsigned int id, IotIoPull val)
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_pull((hi_io_name)id, (hi_io_pull)val);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int IoSetFunc(unsigned int id, unsigned char val)
|
||||||
|
{
|
||||||
|
if (id >= HI_GPIO_IDX_MAX) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_io_set_func((hi_io_name)id, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return IOT_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}*/
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_CONFIG_H
|
||||||
|
#define IOT_CONFIG_H
|
||||||
|
|
||||||
|
// <CONFIG THE LOG
|
||||||
|
/* if you need the iot log for the development , please enable it, else please comment it */
|
||||||
|
#define CONFIG_LINKLOG_ENABLE 1
|
||||||
|
|
||||||
|
// < CONFIG THE WIFI
|
||||||
|
/* Please modify the ssid and pwd for the own */
|
||||||
|
#define CONFIG_AP_SSID "Sidi_iPhone" // WIFI SSID
|
||||||
|
#define CONFIG_AP_PWD "12345678" // WIFI PWD
|
||||||
|
/* Tencent iot Cloud user ID , password */
|
||||||
|
#define CONFIG_USER_ID "YT32IOSCALHi38611_mqtt;12010126;41883;1663689600"
|
||||||
|
#define CONFIG_USER_PWD "b4168d5d4b65898e6984346c81ad13e1b3f112ab7ce46f65cf29455f4c9e18e8;hmacsha256"
|
||||||
|
#define CN_CLIENTID "YT32IOSCALHi38611_mqtt" // Tencent cloud ClientID format: Product ID + device name
|
||||||
|
#endif
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file make use the hmac to make mqtt pwd.
|
||||||
|
* The method is use the date string to hash the device passwd
|
||||||
|
* Take care that this implement depends on the hmac of the mbedtls
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "md.h"
|
||||||
|
#include "md_internal.h"
|
||||||
|
|
||||||
|
#define CN_HMAC256_LEN_MAX (65)
|
||||||
|
#define CN_HMAC256_LEN 32
|
||||||
|
#define RIGHT_MOVE_BIT_4 (4)
|
||||||
|
#define NUMBER_9 (9)
|
||||||
|
#define DECIMAL_BASE (10)
|
||||||
|
#define STRING_LEN_TIMES (2)
|
||||||
|
#define LEN_TIMES (2)
|
||||||
|
#define OFFSET (1)
|
||||||
|
// make a byte to 2 ascii hex
|
||||||
|
static int byte2hexstr(unsigned char *bufin, int len, char *bufout)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
unsigned char tmp_l = 0x0;
|
||||||
|
unsigned char tmp_h = 0;
|
||||||
|
if ((bufin == NULL)||(len <= 0)||(bufout == NULL)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
tmp_h = (bufin[i] >> RIGHT_MOVE_BIT_4) & 0X0F;
|
||||||
|
tmp_l = bufin[i] & 0x0F;
|
||||||
|
bufout[STRING_LEN_TIMES * i] = (tmp_h > NUMBER_9) ?
|
||||||
|
(tmp_h - DECIMAL_BASE + 'a'):(tmp_h +'0');
|
||||||
|
bufout[STRING_LEN_TIMES * i + OFFSET] = (tmp_l > NUMBER_9) ?
|
||||||
|
(tmp_l - DECIMAL_BASE + 'a'):(tmp_l +'0');
|
||||||
|
}
|
||||||
|
bufout[STRING_LEN_TIMES * len] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HmacGeneratePwd(const unsigned char *content, int contentLen, const unsigned char *key,
|
||||||
|
int keyLen, unsigned char *buf)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
mbedtls_md_context_t mbedtls_md_ctx;
|
||||||
|
const mbedtls_md_info_t *md_info;
|
||||||
|
unsigned char hash[CN_HMAC256_LEN];
|
||||||
|
|
||||||
|
if ((key == NULL)||(content == NULL)||(buf == NULL)||
|
||||||
|
(keyLen == 0)||(contentLen == 0)||
|
||||||
|
(CN_HMAC256_LEN_MAX < (CN_HMAC256_LEN * LEN_TIMES + OFFSET))) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
if ((md_info == NULL)||((size_t)md_info->size > CN_HMAC256_LEN)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(&mbedtls_md_ctx);
|
||||||
|
ret = mbedtls_md_setup(&mbedtls_md_ctx, md_info, 1);
|
||||||
|
if (ret != 0) {
|
||||||
|
mbedtls_md_free(&mbedtls_md_ctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)mbedtls_md_hmac_starts(&mbedtls_md_ctx, key, keyLen);
|
||||||
|
(void)mbedtls_md_hmac_update(&mbedtls_md_ctx, content, contentLen);
|
||||||
|
(void)mbedtls_md_hmac_finish(&mbedtls_md_ctx, hash);
|
||||||
|
|
||||||
|
// <transfer the hash code to the string mode
|
||||||
|
ret = byte2hexstr(hash, CN_HMAC256_LEN, (char *)buf);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iot_log.h>
|
||||||
|
|
||||||
|
static EnIotLogLevel gIoTLogLevel = EN_IOT_LOG_LEVEL_TRACE;
|
||||||
|
static const char *gIoTLogLevelNames[] = {
|
||||||
|
"TRACE",
|
||||||
|
"DEBUG",
|
||||||
|
"INFO ",
|
||||||
|
"WARN ",
|
||||||
|
"ERROR",
|
||||||
|
"FATAL"
|
||||||
|
};
|
||||||
|
|
||||||
|
int IoTLogLevelSet(EnIotLogLevel level)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
if (level < EN_IOT_LOG_LEVEL_MAX) {
|
||||||
|
gIoTLogLevel = level;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnIotLogLevel IoTLogLevelGet(void)
|
||||||
|
{
|
||||||
|
return gIoTLogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *IoTLogLevelGetName(EnIotLogLevel logLevel)
|
||||||
|
{
|
||||||
|
if (logLevel >= EN_IOT_LOG_LEVEL_MAX) {
|
||||||
|
return "NULL ";
|
||||||
|
} else {
|
||||||
|
return gIoTLogLevelNames[logLevel];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_LOG_H_
|
||||||
|
#define IOT_LOG_H_
|
||||||
|
/**
|
||||||
|
* @brief:this defines for the log module,
|
||||||
|
* and IOT_LOG_TRACE/IOT_LOG_DEBUG will not participate the compile in the release version
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
typedef enum {
|
||||||
|
// < this is used as the trace function,like the function enter and function out
|
||||||
|
EN_IOT_LOG_LEVEL_TRACE = 0,
|
||||||
|
// < this is used as the debug, you could add any debug as you wish
|
||||||
|
EN_IOT_LOG_LEVEL_DEBUG,
|
||||||
|
// < which means it is import message, and you should known
|
||||||
|
EN_IOT_LOG_LEVEL_INFO,
|
||||||
|
// < this is used as the executed result,which means the status is not what we expected
|
||||||
|
EN_IOT_LOG_LEVEL_WARN,
|
||||||
|
// < this is used as the executed result,which means the status is not what we expected
|
||||||
|
EN_IOT_LOG_LEVEL_ERROR,
|
||||||
|
// < this is used as the parameters input for the api interface, which could not accepted
|
||||||
|
EN_IOT_LOG_LEVEL_FATAL,
|
||||||
|
EN_IOT_LOG_LEVEL_MAX,
|
||||||
|
}EnIotLogLevel;
|
||||||
|
/**
|
||||||
|
* @brief:use this function to get the current output log
|
||||||
|
*
|
||||||
|
* @return: the current output mask log, defined by en_iot_log_level_t
|
||||||
|
* */
|
||||||
|
EnIotLogLevel IoTLogLevelGet(void);
|
||||||
|
/**
|
||||||
|
* @brief: use this function to get the debug level name
|
||||||
|
*
|
||||||
|
* @parameter[in]:level, the level to get
|
||||||
|
*
|
||||||
|
* @return: the mapped level name
|
||||||
|
* */
|
||||||
|
const char *IoTLogLevelGetName(EnIotLogLevel logLevel);
|
||||||
|
/**
|
||||||
|
* @brief:use this function to set the current output log
|
||||||
|
*
|
||||||
|
* @parameter[in] level:defined by en_iot_log_level_t
|
||||||
|
*
|
||||||
|
* @return: 0 success while -1 failed
|
||||||
|
* */
|
||||||
|
int IoTLogLevelSet(EnIotLogLevel level);
|
||||||
|
/*
|
||||||
|
* @brief: this is a weak function ,and you could rewrite one
|
||||||
|
*
|
||||||
|
* @param fmt: same use as the fmt for printf
|
||||||
|
*
|
||||||
|
* @param unfixed: same use for printf
|
||||||
|
*
|
||||||
|
* @return: don't care about it
|
||||||
|
*
|
||||||
|
* @attention: and the components should not call this function directly, you'd better
|
||||||
|
*
|
||||||
|
* call IOT_LOG groups
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
#ifndef IOT_PRINT
|
||||||
|
#define IOT_PRINT(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
printf(fmt, ##__VA_ARGS__); \
|
||||||
|
}while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINKLOG_ENABLE
|
||||||
|
|
||||||
|
#define IOT_LOG(level, fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
IOT_PRINT("[%s][%s] " fmt "\r\n", \
|
||||||
|
IoTLogLevelGetName((level)), __FUNCTION__, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if ((EN_IOT_LOG_LEVEL_TRACE) >= IoTLogLevelGet()) \
|
||||||
|
{ \
|
||||||
|
IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define IOT_LOG_DEBUG(fmt, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if ((EN_IOT_LOG_LEVEL_DEBUG) >= IoTLogLevelGet()) \
|
||||||
|
{ \
|
||||||
|
IOT_LOG(EN_IOT_LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define IOT_LOG(level, fmt, ...)
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...)
|
||||||
|
#define IOT_LOG_DEBUG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IOT_LOG_TRACE(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_TRACE, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_INFO(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_WARN(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_ERROR(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
|
||||||
|
#define IOT_LOG_FATAL(fmt, ...) IOT_LOG(EN_IOT_LOG_LEVEL_FATAL, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif /* IOT_LOG_H_ */
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_MAIN_H
|
||||||
|
#define IOT_MAIN_H
|
||||||
|
|
||||||
|
typedef void (*fnMsgCallBack)(int qos, const char *topic, const char *payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the iot main function. Please call this function first
|
||||||
|
*/
|
||||||
|
int IoTMain(void);
|
||||||
|
/**
|
||||||
|
* Use this function to set the message call back function, when some messages comes,
|
||||||
|
* the callback will be called, if you don't care about the message, set it to NULL
|
||||||
|
*/
|
||||||
|
int IoTSetMsgCallback(fnMsgCallBack msgCallback);
|
||||||
|
/**
|
||||||
|
* When you want to send some messages to the iot server(including the response message),
|
||||||
|
* please call this api
|
||||||
|
* @param qos: the mqtt qos,:0,1,2
|
||||||
|
* @param topic: the iot mqtt topic
|
||||||
|
* @param payload: the mqtt payload
|
||||||
|
*
|
||||||
|
* @return 0 success while others failed
|
||||||
|
*
|
||||||
|
* @instruction: if success means we write the message to the queue susccess,
|
||||||
|
* not means communicate with the server success
|
||||||
|
*/
|
||||||
|
int IotSendMsg(int qos, const char *topic, const char *payload);
|
||||||
|
|
||||||
|
#endif /* IOT_MAIN_H_ */
|
@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_mem.h>
|
||||||
|
#include <cJSON.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "iot_main.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_profile.h"
|
||||||
|
|
||||||
|
// < format the report data to json string mode
|
||||||
|
static cJSON *FormateProflleValue(IoTProfileKV_t *kv)
|
||||||
|
{
|
||||||
|
cJSON *ret = NULL;
|
||||||
|
switch (kv->type) {
|
||||||
|
case EN_IOT_DATATYPE_INT:
|
||||||
|
ret = cJSON_CreateNumber(kv->iValue);
|
||||||
|
break;
|
||||||
|
case EN_IOT_DATATYPE_LONG:
|
||||||
|
ret = cJSON_CreateNumber((double)(*(long *)kv->value));
|
||||||
|
break;
|
||||||
|
case EN_IOT_DATATYPE_STRING:
|
||||||
|
ret = cJSON_CreateString((const char *)kv->value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON *MakeKvs(IoTProfileKV_t *kvlst)
|
||||||
|
{
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *kv;
|
||||||
|
IoTProfileKV_t *kvInfo;
|
||||||
|
|
||||||
|
// < build a root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
// < add all the property to the properties
|
||||||
|
kvInfo = kvlst;
|
||||||
|
while (kvInfo != NULL) {
|
||||||
|
kv = FormateProflleValue(kvInfo);
|
||||||
|
if (kv == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObject(root, kvInfo->key, kv);
|
||||||
|
kvInfo = kvInfo->nxt;
|
||||||
|
}
|
||||||
|
// < OK, now we return it
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_SERVICEID "service_id"
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_PROPERTIIES "properties"
|
||||||
|
#define CN_PROFILE_SERVICE_KEY_EVENTTIME "event_time"
|
||||||
|
#define CN_PROFILE_KEY_SERVICES "services"
|
||||||
|
static cJSON *MakeService(IoTProfileService_t *serviceInfo)
|
||||||
|
{
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *serviceID;
|
||||||
|
cJSON *properties;
|
||||||
|
cJSON *eventTime;
|
||||||
|
|
||||||
|
// < build a root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
// < add the serviceID node to the root node
|
||||||
|
serviceID = cJSON_CreateString(serviceInfo->serviceID);
|
||||||
|
if (serviceID == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_SERVICEID, serviceID);
|
||||||
|
// < add the properties node to the root
|
||||||
|
properties = MakeKvs(serviceInfo->serviceProperty);
|
||||||
|
if (properties == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_PROPERTIIES, properties);
|
||||||
|
// < add the event time (optional) to the root
|
||||||
|
if (serviceInfo->eventTime != NULL) {
|
||||||
|
eventTime = cJSON_CreateString(serviceInfo->eventTime);
|
||||||
|
if (eventTime == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
root = NULL;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_SERVICE_KEY_EVENTTIME, eventTime);
|
||||||
|
}
|
||||||
|
// < OK, now we return it
|
||||||
|
cJSON_Delete(properties);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
static cJSON *MakeServices(IoTProfileService_t *serviceInfo)
|
||||||
|
{
|
||||||
|
cJSON *services = NULL;
|
||||||
|
cJSON *service;
|
||||||
|
IoTProfileService_t *serviceTmp;
|
||||||
|
|
||||||
|
// < create the services array node
|
||||||
|
services = cJSON_CreateArray();
|
||||||
|
if (services == NULL) {
|
||||||
|
cJSON_Delete(services);
|
||||||
|
services = NULL;
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceTmp = serviceInfo;
|
||||||
|
while (serviceTmp != NULL) {
|
||||||
|
service = MakeService(serviceTmp);
|
||||||
|
if (service == NULL) {
|
||||||
|
if (services != NULL) {
|
||||||
|
cJSON_Delete(services);
|
||||||
|
services = NULL;
|
||||||
|
}
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToArray(services, service);
|
||||||
|
serviceTmp = serviceTmp->nxt;
|
||||||
|
}
|
||||||
|
// < now we return the services
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
// < use this function to make a topic to publish
|
||||||
|
// < if request_id is needed depends on the fmt
|
||||||
|
static char *MakeTopic(const char *fmt, const char *deviceID, const char *requestID)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
char *ret = NULL;
|
||||||
|
|
||||||
|
len = strlen(fmt) + strlen(deviceID);
|
||||||
|
if (requestID != NULL) {
|
||||||
|
len += strlen(requestID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hi_malloc(0, len);
|
||||||
|
if (ret != NULL) {
|
||||||
|
if (requestID != NULL) {
|
||||||
|
(void)snprintf_s(ret, len, len, fmt, deviceID, requestID);
|
||||||
|
} else {
|
||||||
|
(void)snprintf_s(ret, len, len, fmt, deviceID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_RETCODE "result_code"
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_RESPNAME "response_name"
|
||||||
|
#define CN_PROFILE_CMDRESP_KEY_PARAS "paras"
|
||||||
|
static char *MakeProfileCmdResp(IoTCmdResp_t *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *retCode;
|
||||||
|
cJSON *respName;
|
||||||
|
cJSON *paras;
|
||||||
|
|
||||||
|
// < create the root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// < create retcode and retdesc and add it to the root
|
||||||
|
retCode = cJSON_CreateNumber(payload->retCode);
|
||||||
|
if (retCode == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RETCODE, retCode);
|
||||||
|
if (payload->respName != NULL) {
|
||||||
|
respName = cJSON_CreateString(payload->respName);
|
||||||
|
if (respName == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_RESPNAME, respName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payload->paras != NULL) {
|
||||||
|
paras = MakeKvs(payload->paras);
|
||||||
|
if (paras == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_CMDRESP_KEY_PARAS, paras);
|
||||||
|
}
|
||||||
|
// < OK, now we make it to a buffer
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *MakeProfilePropertyReport(IoTProfileService_t *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *services;
|
||||||
|
|
||||||
|
// < create the root node
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// < create the services array node to the root
|
||||||
|
services = MakeServices(payload);
|
||||||
|
if (services == NULL) {
|
||||||
|
if (root != NULL) {
|
||||||
|
cJSON_Delete(root);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cJSON_AddItemToObjectCS(root, CN_PROFILE_KEY_SERVICES, services);
|
||||||
|
// < OK, now we make it to a buffer
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WECHAT_SUBSCRIBE_TYPE "update"
|
||||||
|
#define WECHAT_SUBSCRIBE_VERSION "1.0.0"
|
||||||
|
#define WECHAT_SUBSCRIBE_TOKEN "DeviceSubscribe"
|
||||||
|
static char *MakeProfileReport(WeChatProfile *payload)
|
||||||
|
{
|
||||||
|
char *ret = NULL;
|
||||||
|
cJSON *root;
|
||||||
|
cJSON *state;
|
||||||
|
cJSON *reported;
|
||||||
|
|
||||||
|
/* create json root node */
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* state create */
|
||||||
|
state = cJSON_CreateObject();
|
||||||
|
if (state == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* reported create */
|
||||||
|
reported = cJSON_CreateObject();
|
||||||
|
if (reported == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* add root object */
|
||||||
|
cJSON_AddItemToObject(root, payload->subscribeType, cJSON_CreateString(WECHAT_SUBSCRIBE_TYPE));
|
||||||
|
cJSON_AddItemToObject(root, payload->status.subState, state);
|
||||||
|
cJSON_AddItemToObject(state, payload->status.subReport, reported);
|
||||||
|
cJSON_AddItemToObject(root, payload->status.reportVersion, cJSON_CreateString(WECHAT_SUBSCRIBE_VERSION));
|
||||||
|
cJSON_AddItemToObject(root, payload->status.Token, cJSON_CreateString(WECHAT_SUBSCRIBE_TOKEN));
|
||||||
|
/* add reported item */
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLight,
|
||||||
|
payload->reportAction.lightActionStatus);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionMotor,
|
||||||
|
payload->reportAction.motorActionStatus);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionTemperature,
|
||||||
|
payload->reportAction.temperatureData);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionHumidity,
|
||||||
|
payload->reportAction.humidityActionData);
|
||||||
|
cJSON_AddNumberToObject(reported, payload->reportAction.subDeviceActionLightIntensity,
|
||||||
|
payload->reportAction.lightIntensityActionData);
|
||||||
|
ret = cJSON_PrintUnformatted(root);
|
||||||
|
cJSON_Delete(state);
|
||||||
|
cJSON_Delete(reported);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CN_PROFILE_TOPICFMT_TOPIC "YT32IOSCAL/Hi38611_mqtt/data"
|
||||||
|
int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *topic;
|
||||||
|
char *msg;
|
||||||
|
|
||||||
|
if ((deviceID == NULL) || (payload== NULL)) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
topic = MakeTopic(CN_PROFILE_TOPICFMT_TOPIC, deviceID, NULL);
|
||||||
|
if (topic == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg = MakeProfileReport(payload);
|
||||||
|
if ((topic != NULL) && (msg != NULL)) {
|
||||||
|
ret = IotSendMsg(0, topic, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
hi_free(0, topic);
|
||||||
|
cJSON_free(msg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IOT_PROFILE_H
|
||||||
|
#define IOT_PROFILE_H
|
||||||
|
|
||||||
|
#include <hi_types_base.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
|
||||||
|
#define OC_BEEP_STATUS_ON ((hi_u8) 0x01)
|
||||||
|
#define OC_BEEP_STATUS_OFF ((hi_u8) 0x00)
|
||||||
|
|
||||||
|
// < enum all the data type for the oc profile
|
||||||
|
typedef enum {
|
||||||
|
EN_IOT_DATATYPE_INT = 0,
|
||||||
|
EN_IOT_DATATYPE_LONG,
|
||||||
|
EN_IOT_DATATYPE_FLOAT,
|
||||||
|
EN_IOT_DATATYPE_DOUBLE,
|
||||||
|
EN_IOT_DATATYPE_STRING, // < must be ended with '\0'
|
||||||
|
EN_IOT_DATATYPE_LAST,
|
||||||
|
}IoTDataType_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OC_LED_ON = 1,
|
||||||
|
OC_LED_OFF
|
||||||
|
}OcLedValue;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *nxt; // < ponit to the next key
|
||||||
|
const char *key;
|
||||||
|
const char *value;
|
||||||
|
hi_u32 iValue;
|
||||||
|
IoTDataType_t type;
|
||||||
|
}IoTProfileKV_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *nxt;
|
||||||
|
char *serviceID;
|
||||||
|
char *eventTime;
|
||||||
|
IoTProfileKV_t *serviceProperty;
|
||||||
|
}IoTProfileService_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int retCode; // < response code, 0 success while others failed
|
||||||
|
const char *respName; // < response name
|
||||||
|
const char *requestID; // < specified by the message command
|
||||||
|
IoTProfileKV_t *paras; // < the command paras
|
||||||
|
}IoTCmdResp_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *subState;
|
||||||
|
const char *subReport;
|
||||||
|
const char *reportVersion;
|
||||||
|
const char *Token;
|
||||||
|
}WeChatProfileStatus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int lightActionStatus;
|
||||||
|
int motorActionStatus;
|
||||||
|
int temperatureData;
|
||||||
|
int humidityActionData;
|
||||||
|
int lightIntensityActionData;
|
||||||
|
const char *subDeviceActionLight;
|
||||||
|
const char *subDeviceActionMotor;
|
||||||
|
const char *subDeviceActionTemperature;
|
||||||
|
const char *subDeviceActionHumidity;
|
||||||
|
const char *subDeviceActionLightIntensity;
|
||||||
|
}WeChatProfileReporte;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *subscribeType;
|
||||||
|
WeChatProfileStatus status;
|
||||||
|
WeChatProfileReporte reportAction;
|
||||||
|
}WeChatProfile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* use this function to report the property to the iot platform
|
||||||
|
*/
|
||||||
|
int IoTProfilePropertyReport(char *deviceID, WeChatProfile *payload);
|
||||||
|
void cJsonInit(void);
|
||||||
|
void WifiStaReadyWait(void);
|
||||||
|
#endif
|
@ -0,0 +1,269 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// < this demo make the wifi to connect to the specified AP
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <hi_wifi_api.h>
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
#include <lwip/netifapi.h>
|
||||||
|
#include <hi_types_base.h>
|
||||||
|
#include <hi_task.h>
|
||||||
|
#include <hi_mem.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "wifi_device.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
#include "wifi_device_config.h"
|
||||||
|
#include "lwip/api_shell.h"
|
||||||
|
|
||||||
|
#define APP_INIT_VAP_NUM 2
|
||||||
|
#define APP_INIT_USR_NUM 2
|
||||||
|
|
||||||
|
static struct netif *gLwipNetif = NULL;
|
||||||
|
static hi_bool gScanDone = HI_FALSE;
|
||||||
|
unsigned char wifiStatus = 0;
|
||||||
|
|
||||||
|
unsigned char wifiFirstConnecting = 0;
|
||||||
|
unsigned char wifiSecondConnecting = 0;
|
||||||
|
unsigned char wifiSecondConnected = 0;
|
||||||
|
static struct netif* g_iface = NULL;
|
||||||
|
void WifiStopSta(int netId);
|
||||||
|
static int WifiStartSta(void);
|
||||||
|
int cnetId = -1;
|
||||||
|
int g_connected = 0;
|
||||||
|
|
||||||
|
#define WIFI_CONNECT_STATUS ((unsigned char)0x02)
|
||||||
|
|
||||||
|
void wifiReconnected(int netId)
|
||||||
|
{
|
||||||
|
int recnetId = netId;
|
||||||
|
if (wifiFirstConnecting == WIFI_CONNECT_STATUS) {
|
||||||
|
wifiSecondConnecting = HI_TRUE;
|
||||||
|
wifiFirstConnecting = HI_FALSE;
|
||||||
|
WifiStopSta(recnetId);
|
||||||
|
ip4_addr_t ipAddr;
|
||||||
|
ip4_addr_t ipAny;
|
||||||
|
IP4_ADDR(&ipAny, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
|
||||||
|
recnetId = WifiStartSta();
|
||||||
|
netifapi_dhcp_start(gLwipNetif);
|
||||||
|
while (0 == memcmp(&ipAddr, &ipAny, sizeof(ip4_addr_t))) {
|
||||||
|
IOT_LOG_DEBUG("<Wifi reconnecting>:Wait the DHCP READY");
|
||||||
|
netifapi_netif_get_addr(gLwipNetif, &ipAddr, NULL, NULL);
|
||||||
|
hi_sleep(1000); /* 1000: cpu sleep 1000 ms */
|
||||||
|
}
|
||||||
|
wifiSecondConnected = HI_FALSE;
|
||||||
|
wifiFirstConnecting = WIFI_CONNECT_STATUS;
|
||||||
|
wifiStatus = HI_WIFI_EVT_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* clear netif's ip, gateway and netmask */
|
||||||
|
static void StaResetAddr(struct netif *lwipNetif)
|
||||||
|
{
|
||||||
|
ip4_addr_t st_gw;
|
||||||
|
ip4_addr_t st_ipaddr;
|
||||||
|
ip4_addr_t st_netmask;
|
||||||
|
|
||||||
|
if (lwipNetif == NULL) {
|
||||||
|
IOT_LOG_ERROR("hisi_reset_addr::Null param of netdev");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IP4_ADDR(&st_gw, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&st_netmask, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
netifapi_netif_set_addr(lwipNetif, &st_ipaddr, &st_netmask, &st_gw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WpaEventCB(const hi_wifi_event *hisiEvent)
|
||||||
|
{
|
||||||
|
if (hisiEvent == NULL)
|
||||||
|
return;
|
||||||
|
IOT_LOG_DEBUG("EVENT_TYPE:%d", hisiEvent->event);
|
||||||
|
switch (hisiEvent->event) {
|
||||||
|
case HI_WIFI_EVT_SCAN_DONE:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Scan results available");
|
||||||
|
gScanDone = HI_TRUE;
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_CONNECTED:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Connected");
|
||||||
|
netifapi_dhcp_start(gLwipNetif);
|
||||||
|
wifiStatus = HI_WIFI_EVT_CONNECTED;
|
||||||
|
if (wifiSecondConnected) {
|
||||||
|
wifiSecondConnected = HI_FALSE;
|
||||||
|
wifiFirstConnecting = WIFI_CONNECT_STATUS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_DISCONNECTED:
|
||||||
|
IOT_LOG_DEBUG("WiFi: Disconnected");
|
||||||
|
netifapi_dhcp_stop(gLwipNetif);
|
||||||
|
StaResetAddr(gLwipNetif);
|
||||||
|
wifiStatus = HI_WIFI_EVT_DISCONNECTED;
|
||||||
|
wifiReconnected(cnetId);
|
||||||
|
break;
|
||||||
|
case HI_WIFI_EVT_WPS_TIMEOUT:
|
||||||
|
IOT_LOG_DEBUG("WiFi: wps is timeout");
|
||||||
|
wifiStatus = HI_WIFI_EVT_WPS_TIMEOUT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int StaStartConnect(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
errno_t rc;
|
||||||
|
hi_wifi_assoc_request assoc_req = {0};
|
||||||
|
|
||||||
|
/* copy SSID to assoc_req */
|
||||||
|
rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, CONFIG_AP_SSID, strlen(CONFIG_AP_SSID));
|
||||||
|
if (rc != EOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OPEN mode
|
||||||
|
* for WPA2-PSK mode:
|
||||||
|
* set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
|
||||||
|
* then memcpy(assoc_req.key, "12345678", 8).
|
||||||
|
*/
|
||||||
|
assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;
|
||||||
|
rc = memcpy_s(assoc_req.key, HI_WIFI_MAX_KEY_LEN + 1, CONFIG_AP_PWD, strlen(CONFIG_AP_PWD));
|
||||||
|
if (rc != EOK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hi_wifi_sta_connect(&assoc_req);
|
||||||
|
if (ret != HISI_OK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PrintLinkedInfo(WifiLinkedInfo* info)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char macAddress[32] = {0};
|
||||||
|
unsigned char* mac = info->bssid;
|
||||||
|
if (snprintf_s(macAddress, sizeof(macAddress) + 1, sizeof(macAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
|
||||||
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) < 0) { /* mac地址从0,1,2,3,4,5位 */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnWifiConnectionChanged(int state, WifiLinkedInfo* info)
|
||||||
|
{
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s %d, state = %d, info = \r\n", __FUNCTION__, __LINE__, state);
|
||||||
|
PrintLinkedInfo(info);
|
||||||
|
|
||||||
|
if (state == WIFI_STATE_AVALIABLE) {
|
||||||
|
g_connected = 1;
|
||||||
|
} else {
|
||||||
|
g_connected = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnWifiScanStateChanged(int state, int size)
|
||||||
|
{
|
||||||
|
printf("%s %d, state = %X, size = %d\r\n", __FUNCTION__, __LINE__, state, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WifiEvent g_defaultWifiEventListener = {
|
||||||
|
.OnWifiConnectionChanged = OnWifiConnectionChanged,
|
||||||
|
.OnWifiScanStateChanged = OnWifiScanStateChanged
|
||||||
|
};
|
||||||
|
|
||||||
|
static int WifiStartSta(void)
|
||||||
|
{
|
||||||
|
WifiDeviceConfig apConfig = {0};
|
||||||
|
strcpy_s(apConfig.ssid, sizeof(CONFIG_AP_SSID), CONFIG_AP_SSID);
|
||||||
|
strcpy_s(apConfig.preSharedKey, sizeof(CONFIG_AP_PWD), CONFIG_AP_PWD);
|
||||||
|
apConfig.securityType = WIFI_SEC_TYPE_PSK;
|
||||||
|
|
||||||
|
WifiErrorCode errCode;
|
||||||
|
int netId = -1;
|
||||||
|
|
||||||
|
errCode = RegisterWifiEvent(&g_defaultWifiEventListener);
|
||||||
|
printf("RegisterWifiEvent: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = EnableWifi();
|
||||||
|
printf("EnableWifi: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = AddDeviceConfig(&apConfig, &netId);
|
||||||
|
printf("AddDeviceConfig: %d\r\n", errCode);
|
||||||
|
|
||||||
|
g_connected = 0;
|
||||||
|
errCode = ConnectTo(netId);
|
||||||
|
printf("ConnectTo(%d): %d\r\n", netId, errCode);
|
||||||
|
|
||||||
|
while (!g_connected) { // wait until connect to AP
|
||||||
|
osDelay(10); /* 10: os sleep 10ms */
|
||||||
|
}
|
||||||
|
printf("g_connected: %d\r\n", g_connected);
|
||||||
|
|
||||||
|
g_iface = netifapi_netif_find("wlan0");
|
||||||
|
if (g_iface) {
|
||||||
|
err_t ret = netifapi_dhcp_start(g_iface);
|
||||||
|
printf("netifapi_dhcp_start: %d\r\n", ret);
|
||||||
|
|
||||||
|
osDelay(100); // 100: os sleep 100ms wait DHCP server give me IP
|
||||||
|
ret = netifapi_netif_common(g_iface, dhcp_clients_info_show, NULL);
|
||||||
|
printf("netifapi_netif_common: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
return netId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiStopSta(int netId)
|
||||||
|
{
|
||||||
|
int stopNetId = netId;
|
||||||
|
|
||||||
|
if (g_iface) {
|
||||||
|
err_t ret = netifapi_dhcp_stop(g_iface);
|
||||||
|
printf("netifapi_dhcp_stop: %d\r\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
WifiErrorCode errCode = Disconnect(); // disconnect with your AP
|
||||||
|
printf("Disconnect: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = UnRegisterWifiEvent(&g_defaultWifiEventListener);
|
||||||
|
printf("UnRegisterWifiEvent: %d\r\n", errCode);
|
||||||
|
|
||||||
|
RemoveDevice(stopNetId); // remove AP config
|
||||||
|
printf("RemoveDevice: %d\r\n", errCode);
|
||||||
|
|
||||||
|
errCode = DisableWifi();
|
||||||
|
printf("DisableWifi: %d\r\n", errCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiStaReadyWait(void)
|
||||||
|
{
|
||||||
|
ip4_addr_t ipAddr;
|
||||||
|
ip4_addr_t ipAny;
|
||||||
|
IP4_ADDR(&ipAny, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&ipAddr, 0, 0, 0, 0);
|
||||||
|
cnetId = WifiStartSta();
|
||||||
|
IOT_LOG_DEBUG("wifi sta dhcp done");
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
# Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
static_library("appDemoIot") {
|
||||||
|
sources = [
|
||||||
|
"app_demo_iot.c",
|
||||||
|
"cjson_init.c",
|
||||||
|
"iot_hmac.c",
|
||||||
|
"iot_log.c",
|
||||||
|
"iot_main.c",
|
||||||
|
"iot_profile.c",
|
||||||
|
"iot_sta.c",
|
||||||
|
]
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
"./",
|
||||||
|
"//utils/native/lite/include",
|
||||||
|
"//kernel/liteos_m/kal/cmsis",
|
||||||
|
"//base/iot_hardware/peripheral/interfaces/kits",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/lwip_sack/include/lwip",
|
||||||
|
"//third_party/cJSON",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/mbedtls/include/mbedtls",
|
||||||
|
"//foundation/communication/wifi_lite/interfaces/wifiservice",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/paho.mqtt.c/include/mqtt",
|
||||||
|
"//device/soc/hisilicon/hi3861v100/sdk_liteos/third_party/libcoap/include/coap2",
|
||||||
|
]
|
||||||
|
|
||||||
|
defines = [ "WITH_LWIP" ]
|
||||||
|
}
|
@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <hi_task.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <hi_wifi_api.h>
|
||||||
|
#include <hi_mux.h>
|
||||||
|
#include <hi_io.h>
|
||||||
|
#include <hi_gpio.h>
|
||||||
|
#include "iot_config.h"
|
||||||
|
#include "iot_log.h"
|
||||||
|
#include "iot_main.h"
|
||||||
|
#include "iot_profile.h"
|
||||||
|
#include "ohos_init.h"
|
||||||
|
#include "cmsis_os2.h"
|
||||||
|
|
||||||
|
/* attribute initiative to report */
|
||||||
|
#define TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
#define ONE_SECOND (1000)
|
||||||
|
/* oc request id */
|
||||||
|
#define CN_COMMADN_INDEX "commands/request_id="
|
||||||
|
#define WECHAT_SUBSCRIBE_LIGHT "light"
|
||||||
|
#define WECHAT_SUBSCRIBE_LIGHT_ON_STATE "1"
|
||||||
|
#define WECHAT_SUBSCRIBE_LIGHT_OFF_STATE "0"
|
||||||
|
|
||||||
|
int g_ligthStatus = -1;
|
||||||
|
typedef void (*FnMsgCallBack)(hi_gpio_value val);
|
||||||
|
|
||||||
|
typedef struct FunctionCallback {
|
||||||
|
hi_bool stop;
|
||||||
|
hi_u32 conLost;
|
||||||
|
hi_u32 queueID;
|
||||||
|
hi_u32 iotTaskID;
|
||||||
|
FnMsgCallBack msgCallBack;
|
||||||
|
}FunctionCallback;
|
||||||
|
FunctionCallback g_functinoCallback;
|
||||||
|
|
||||||
|
/* CPU Sleep time Set */
|
||||||
|
unsigned int TaskMsleep(unsigned int ms)
|
||||||
|
{
|
||||||
|
if (ms <= 0) {
|
||||||
|
return HI_ERR_FAILURE;
|
||||||
|
}
|
||||||
|
return hi_sleep((hi_u32)ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DeviceConfigInit(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_GPIO);
|
||||||
|
hi_gpio_set_dir(HI_GPIO_IDX_9, HI_GPIO_DIR_OUT);
|
||||||
|
hi_gpio_set_ouput_val(HI_GPIO_IDX_9, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int DeviceMsgCallback(FnMsgCallBack msgCallBack)
|
||||||
|
{
|
||||||
|
g_functinoCallback.msgCallBack = msgCallBack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wechatControlDeviceMsg(hi_gpio_value val)
|
||||||
|
{
|
||||||
|
DeviceConfigInit(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
// < this is the callback function, set to the mqtt, and if any messages come, it will be called
|
||||||
|
// < The payload here is the json string
|
||||||
|
static void DemoMsgRcvCallBack(int qos, const char *topic, const char *payload)
|
||||||
|
{
|
||||||
|
IOT_LOG_DEBUG("RCVMSG:QOS:%d TOPIC:%s PAYLOAD:%s\r\n", qos, topic, payload);
|
||||||
|
/* 云端下发命令后,板端的操作处理 */
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT) != NULL) {
|
||||||
|
if (strstr(payload, WECHAT_SUBSCRIBE_LIGHT_OFF_STATE) != NULL) {
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE1);
|
||||||
|
g_ligthStatus = HI_FALSE;
|
||||||
|
} else {
|
||||||
|
wechatControlDeviceMsg(HI_GPIO_VALUE0);
|
||||||
|
g_ligthStatus = HI_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return HI_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* publish sample */
|
||||||
|
hi_void IotPublishSample(void)
|
||||||
|
{
|
||||||
|
/* reported attribute */
|
||||||
|
WeChatProfile weChatProfile = {
|
||||||
|
.subscribeType = "type",
|
||||||
|
.status.subState = "state",
|
||||||
|
.status.subReport = "reported",
|
||||||
|
.status.reportVersion = "version",
|
||||||
|
.status.Token = "clientToken",
|
||||||
|
/* report motor */
|
||||||
|
.reportAction.subDeviceActionMotor = "motor",
|
||||||
|
.reportAction.motorActionStatus = 0, /* 0 : motor off */
|
||||||
|
/* report temperature */
|
||||||
|
.reportAction.subDeviceActionTemperature = "temperature",
|
||||||
|
.reportAction.temperatureData = 30, /* 30 :temperature data */
|
||||||
|
/* report humidity */
|
||||||
|
.reportAction.subDeviceActionHumidity = "humidity",
|
||||||
|
.reportAction.humidityActionData = 70, /* humidity data */
|
||||||
|
/* report light_intensity */
|
||||||
|
.reportAction.subDeviceActionLightIntensity = "light_intensity",
|
||||||
|
.reportAction.lightIntensityActionData = 60, /* 60 : light_intensity */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* report light */
|
||||||
|
if (g_ligthStatus == HI_TRUE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 1; /* 1: light on */
|
||||||
|
} else if (g_ligthStatus == HI_FALSE) {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
|
||||||
|
} else {
|
||||||
|
weChatProfile.reportAction.subDeviceActionLight = "light";
|
||||||
|
weChatProfile.reportAction.lightActionStatus = 0; /* 0: light off */
|
||||||
|
}
|
||||||
|
/* profile report */
|
||||||
|
IoTProfilePropertyReport(CONFIG_USER_ID, &weChatProfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// < this is the demo main task entry,here we will set the wifi/cjson/mqtt ready and
|
||||||
|
// < wait if any work to do in the while
|
||||||
|
static hi_void *DemoEntry(const char *arg)
|
||||||
|
{
|
||||||
|
WifiStaReadyWait();
|
||||||
|
cJsonInit();
|
||||||
|
IoTMain();
|
||||||
|
/* 云端下发回调 */
|
||||||
|
IoTSetMsgCallback(DemoMsgRcvCallBack);
|
||||||
|
/* 主动上报 */
|
||||||
|
#ifdef TAKE_THE_INITIATIVE_TO_REPORT
|
||||||
|
while (1) {
|
||||||
|
/* 用户可以在这调用发布函数进行发布,需要用户自己写调用函数 */
|
||||||
|
IotPublishSample(); // 发布例程
|
||||||
|
#endif
|
||||||
|
TaskMsleep(ONE_SECOND);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// < This is the demo entry, we create a task here,
|
||||||
|
// and all the works has been done in the demo_entry
|
||||||
|
#define CN_IOT_TASK_STACKSIZE 0x1000
|
||||||
|
#define CN_IOT_TASK_PRIOR 25
|
||||||
|
#define CN_IOT_TASK_NAME "IOTDEMO"
|
||||||
|
|
||||||
|
static void AppDemoIot(void)
|
||||||
|
{
|
||||||
|
osThreadAttr_t attr;
|
||||||
|
IoTWatchDogDisable();
|
||||||
|
|
||||||
|
attr.name = "IOTDEMO";
|
||||||
|
attr.attr_bits = 0U;
|
||||||
|
attr.cb_mem = NULL;
|
||||||
|
attr.cb_size = 0U;
|
||||||
|
attr.stack_mem = NULL;
|
||||||
|
attr.stack_size = CN_IOT_TASK_STACKSIZE;
|
||||||
|
attr.priority = CN_IOT_TASK_PRIOR;
|
||||||
|
|
||||||
|
if (osThreadNew((osThreadFunc_t)DemoEntry, NULL, &attr) == NULL) {
|
||||||
|
printf("[mqtt] Falied to create IOTDEMO!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SYS_RUN(AppDemoIot);
|