Files
AC_Pro/HelpPanelUnit.cpp
2026-06-13 00:05:19 +08:00

770 lines
18 KiB
C++

//---------------------------------------------------------------------------
#pragma hdrstop
#include "HelpPanelUnit.h"
#include "GlobalUnit.h"
char u_strURLAndroid[256] = "/ichangzuo/File/Software/App/Ac/Android/Ac_Android.apk",
u_strURLiOS[256] = "http://itunes.apple.com/cn/app/id928747575";
const static COLORREF clrEnter = RGB( 100,180,236 ),
clrLeave = RGB( 67,117,233 );
//---------------------------------------------------------------------------
#pragma package(smart_init)
__fastcall THelpPanel::THelpPanel(TComponent* AOwner)
: Vcl::Extctrls::TPanel(AOwner)
{
m_sbVert = NULL;
m_nLeftBound = 15;
m_nRightBound = 48;
m_nTopBound = 15;
m_nBottomBound = 25;
m_nRowWidth = 0;
m_nRowHight = 22;
m_iMode = 0;
m_nBeginShowRow = 0;
for( int i=0; i<MODE_NUM; i++ ){
m_aFirstRow[i] = m_aFirstTitle[i] = 0;
}
// Canvas->Font->Size = 11; //字母字体大小
Canvas->Font->Quality = TFontQuality::fqClearTypeNatural;
for( int i=0; i<SOFTWARE_NUM; i++ ){
m_aLblSWName[i] = NULL;
m_aLblSWLink[i] = NULL;
}
m_lblCoinPage = NULL;
m_pQRPanelAndroid = NULL;
m_pQRPaneliOS = NULL;
m_pQRdataAndroid = NULL;
m_pQRdataiOS = NULL;
Color = RGB( 53,56,63 );
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::CreateWnd(void)
{
Vcl::Extctrls::TPanel::CreateWnd();
m_sbVert = new TSkinScrollBar(this);
m_sbVert->Parent = this;
m_sbVert->m_pWndCtrl = this;
m_sbVert->Visible = false;
m_sbVert->Left = Width - m_sbVert->Width - 1; //change
m_sbVert->Top = 1;
m_sbVert->Height = Height-2;
m_sbVert->Visible = false;
CalcViewArea();
m_lblCoinPage = new TLabel( NULL );
m_lblCoinPage->Visible = false;
m_lblCoinPage->Parent = this;
m_lblCoinPage->Font->Name = "Tahoma";
m_lblCoinPage->Font->Size = Canvas->Font->Size;
m_lblCoinPage->Font->Style = TFontStyles()<<fsUnderline;
m_lblCoinPage->Font->Color = clrLeave;
m_lblCoinPage->Caption = "官网详细说明";
m_lblCoinPage->OnClick = LinkClick;
m_lblCoinPage->OnMouseEnter = LinkMouseEnter;
m_lblCoinPage->OnMouseLeave = LinkMouseLeave;
m_lblCoinPage->Left = m_nLeftBound + 20;
// m_lblCoinPage->Top = 1;
for( int i=0; i<SOFTWARE_NUM; i++ ){
m_aLblSWName[i] = new TLabel( NULL );
m_aLblSWName[i]->Visible = false;
m_aLblSWName[i]->Parent = this;
m_aLblSWName[i]->Font->Name = g_strTxtFontName;
m_aLblSWName[i]->Font->Color = COLOR_ANSWER;
// if( !strcmp( g_strTxtFontName, "微软雅黑" ) )
// m_aLblSWName[i]->Font->Size = 11;
// else
// m_aLblSWName[i]->Font->Size = 10;
m_aLblSWName[i]->Font->Size = g_szFont10;
m_aLblSWName[i]->Left = m_nLeftBound + 10;
if( i==0 ){
m_aLblSWName[i]->Top = m_nTopBound + 10;
}
else if( i==1 ){
m_aLblSWName[i]->Top = m_aLblSWName[i-1]->Top + 90;
}
else{
m_aLblSWName[i]->Top = m_aLblSWName[i-1]->Top + 110;
}
m_aLblSWLink[i] = new TLabel( NULL );
m_aLblSWLink[i]->Visible = false;
m_aLblSWLink[i]->Parent = this;
m_aLblSWLink[i]->Tag = i;
m_aLblSWLink[i]->Font->Name = "Tahoma";
m_aLblSWLink[i]->Font->Size = g_szFont9;
m_aLblSWLink[i]->Font->Style = TFontStyles()<<fsUnderline;
m_aLblSWLink[i]->Font->Color = clrLeave;
m_aLblSWLink[i]->Caption = "官网免费下载";
m_aLblSWLink[i]->OnClick = LinkClick;
m_aLblSWLink[i]->OnMouseEnter = LinkMouseEnter;
m_aLblSWLink[i]->OnMouseLeave = LinkMouseLeave;
m_aLblSWLink[i]->Left = 250;
m_aLblSWLink[i]->Top = m_aLblSWName[i]->Top + 1;
}
m_aLblSWName[0]->Caption = "唱作魔方 for Windows";
m_aLblSWName[1]->Caption = "唱作魔方App for Android";
m_aLblSWName[2]->Caption = "唱作魔方App for iOS";
if( f_QR_Encode ){
char strURL[256] = "";
f_CS_GetWebPageURL( URL_HOMEPAGE, strURL );
strcat( strURL, u_strURLAndroid );
m_pQRdataAndroid = new unsigned char[100*100];
m_pQRdataiOS = new unsigned char[100*100];
int qrWidthA = f_QR_Encode( strURL, m_pQRdataAndroid ),
qrWidthI = f_QR_Encode( u_strURLiOS, m_pQRdataiOS );
m_pQRPanelAndroid = new TQRcodePanel( NULL, "扫描下载" );
if( m_pQRPanelAndroid ){
m_pQRPanelAndroid->Hide();
m_pQRPanelAndroid->Parent = this;
m_pQRPanelAndroid->SetBounds( 350, 75, 100, 100 );
m_pQRPanelAndroid->SetQRData( qrWidthA, m_pQRdataAndroid );
}
m_pQRPaneliOS = new TQRcodePanel( NULL, "扫描下载" );
if( m_pQRPaneliOS ){
m_pQRPaneliOS->Hide();
m_pQRPaneliOS->Parent = this;
m_pQRPaneliOS->SetBounds( 350, 195, 100, 100 );
m_pQRPaneliOS->SetQRData( qrWidthI, m_pQRdataiOS );
}
}
}
//---------------------------------------------------------------------------
__fastcall THelpPanel::~THelpPanel()
{
for( int i=0; i<SOFTWARE_NUM; i++ ){
delete m_aLblSWName[i];
m_aLblSWName[i] = NULL;
delete m_aLblSWLink[i];
m_aLblSWLink[i] = NULL;
}
if( m_lblCoinPage ){
delete m_lblCoinPage;
m_lblCoinPage = NULL;
}
if( m_pQRPanelAndroid ){
delete m_pQRPanelAndroid;
m_pQRPanelAndroid = NULL;
}
if( m_pQRdataAndroid ){
delete[] m_pQRdataAndroid;
m_pQRdataAndroid = NULL;
}
if( m_pQRPaneliOS ){
delete m_pQRPaneliOS;
m_pQRPaneliOS = NULL;
}
if( m_pQRdataiOS ){
delete[] m_pQRdataiOS;
m_pQRdataiOS = NULL;
}
if( m_sbVert )
delete m_sbVert;
while( !m_lstLines.empty() ){
delete m_lstLines[0];
m_lstLines.erase(m_lstLines.begin());
}
}
//---------------------------------------------------------------------------
void THelpPanel::SetTextFontSize(int sz)
{
Canvas->Font->Size = sz;
if( m_lblCoinPage )
m_lblCoinPage->Font->Size = sz;
}
//---------------------------------------------------------------------------
void THelpPanel::InitialVars()
{
RefreshTextLines();
CalcViewArea();
Invalidate();
}
//---------------------------------------------------------------------------
void THelpPanel::ScrollView( int nPos, bool bRedraw )
{
if( m_nBeginShowRow!=nPos ){
m_nBeginShowRow = nPos;
Invalidate();
}
if( bRedraw ){
m_sbVert->SetPosition( nPos );
}
}
//---------------------------------------------------------------------------
void THelpPanel::CalcViewArea()
{
if( !m_sbVert )
return;
m_nRowNum = m_lstLines.size();
if( m_nRowNum>0 ){
int iFirstRow = m_aFirstRow[m_iMode];
if( iFirstRow<0 ){
int iFirstTitle = m_aFirstTitle[m_iMode];
for( iFirstRow=0; iFirstRow<m_nRowNum && iFirstTitle>0; iFirstRow++ ){
if( m_lstLines[iFirstRow]->strText.empty() ){
iFirstTitle--;
}
}
}
m_nBeginShowRow = iFirstRow;
}
if( m_nRowNum>m_nRowShow ){ //显示滚动条
m_sbVert->Visible = true;
m_sbVert->SetRange( 0, m_nRowNum-1 );
m_sbVert->SetPageSize( m_nRowShow );
m_sbVert->SetPosition( 0 );
//计算显示的第一行
int iRowScroll = 0;
if( m_nBeginShowRow>0 ){
iRowScroll = min( m_nBeginShowRow, m_nRowNum-m_nRowShow );
if( iRowScroll<0 ){
iRowScroll = 0;
}
}
ScrollView( iRowScroll );
}
else{
m_nBeginShowRow = 0;
m_sbVert->Visible = false;
}
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::Paint()
{
if( m_iMode<5 && !m_lstLines.empty() ){
int xPos = m_nLeftBound,
yPos = m_nTopBound;
TColor clrOld = Canvas->Font->Color;
Canvas->Brush->Style = bsClear;
int flag = 0;
for( int i=0; i<m_lstLines.size(); i++ ){
TLineString* pLine = m_lstLines[i];
if( pLine->flag>0 && pLine->flag!=flag ){
flag = pLine->flag;
if( flag==1 ){
Canvas->Font->Color = COLOR_QUESTION;
if( m_iMode<2 )
Canvas->Font->Style = TFontStyles()<<fsBold;
}
else{
Canvas->Font->Color = COLOR_ANSWER;
Canvas->Font->Style = TFontStyles();
}
}
if( i>=m_nBeginShowRow ){
char strFlag[10];
if( pLine->flag==1 ){
if( m_iMode<2 )
strcpy( strFlag, "Q:" );
else{
strcpy( strFlag, "△" );
}
Canvas->TextOut( xPos, yPos, strFlag );
}
else if( pLine->flag==2 ){
if( m_iMode<2 )
strcpy( strFlag, "A:" );
else{
strcpy( strFlag, " " );
}
Canvas->TextOut( xPos, yPos, strFlag );
}
else if(pLine->flag == 3)
{
strcpy( strFlag, "●" );
Canvas->Font->Color = RGB( 207,169,207 ); //question Color
Canvas->Font->Style = TFontStyles() << fsBold;
Canvas->TextOut( xPos, yPos, strFlag );
//Canvas->Font->Color = RGB(0, 0, 255);
}
Canvas->TextOut( xPos+20, yPos, pLine->strText.c_str() );
yPos += m_nRowHight;
}
if( i-m_nBeginShowRow >= m_nRowShow ){
break;
}
}
Canvas->Font->Color = clrOld;
Canvas->Font->Style = TFontStyles();
}
Canvas->Pen->Color = RGB( 53,56,63 );
Canvas->MoveTo( 39 + m_iMode*70 ,0 );
Canvas->LineTo( 39 + m_iMode*70 + 78,0 );
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::WMEraseBkgnd(Winapi::Messages::TWMEraseBkgnd &Message)
{
TCanvas* tempCanvas = new TCanvas;
tempCanvas->Handle = Message.DC;
TRect rect = GetClientRect();
//绘制底图
tempCanvas->Brush->Color = RGB( 53,56,63 );
tempCanvas->FillRect(rect);
//绘制外边框
tempCanvas->Brush->Color = RGB( 43,47,50 );
tempCanvas->FrameRect(rect);
delete tempCanvas;
Message.Result = true;
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::WMSize(Winapi::Messages::TWMSize &Message)
{
DefaultHandler( &Message );
if( m_sbVert ){
m_sbVert->Left = Width - m_sbVert->Width - 1;
m_sbVert->Top = 1;
m_sbVert->Height = Height - 2;
}
m_nRowWidth = Width - m_nLeftBound - m_nRightBound;
m_nRowShow = (Height - m_nTopBound - m_nBottomBound) / m_nRowHight;
SaveFirstRow();
for(int i=0; i<MODE_NUM; i++ ){
m_aFirstRow[i] = -1; //第一行无效
}
RefreshTextLines();
CalcViewArea();
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::WMVScroll(Winapi::Messages::TWMScroll &Message)
{
int minpos, maxpos, page, curpos;
m_sbVert->GetScrollRange(&minpos, &maxpos);
page = m_sbVert->GetPageSize();
// Get the current position of scroll box.
curpos = m_sbVert->GetScrollPos();
// Determine the new position of scroll box.
switch (Message.ScrollCode)
{
case SB_TOP: // Scroll to far top.
curpos = minpos;
break;
case SB_BOTTOM: // Scroll to far bottom.
curpos = maxpos-page+1;
break;
case SB_ENDSCROLL: // End scroll.
break;
case SB_LINEUP: // Scroll left.
if (curpos > minpos)
curpos--;
break;
case SB_LINEDOWN: // Scroll right.
if (curpos < maxpos-page+1)
curpos++;
break;
case SB_PAGEUP: // Scroll one page left.
if (curpos > minpos)
curpos = (minpos > curpos-page) ? minpos : curpos-page;
//max(minpos, curpos-page);
break;
case SB_PAGEDOWN: // Scroll one page right.
if( curpos<maxpos )
curpos = (maxpos-page+1 < curpos+page) ? maxpos-page+1 : curpos+page;
//min(maxpos-page+1, curpos+page);
break;
case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
curpos = Message.Pos; // of the scroll box at the end of the drag operation.
break;
case SB_THUMBTRACK: // Drag scroll box to specified position. nPos is the
curpos = Message.Pos; // position that the scroll box has been dragged to.
break;
}
// Set the new position of the thumb (scroll box).
if( Message.ScrollBar!=m_sbVert->Handle )
m_sbVert->SetPosition(curpos);
ScrollView(curpos, FALSE);
Message.Result = true;
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::WMMouseWheel(TWMMouseWheel &Message)
{
if( m_sbVert->Visible ){
UINT nSBCode;
if( Message.WheelDelta>0 ) nSBCode = SB_LINEUP;
else nSBCode = SB_LINEDOWN;
Perform( WM_VSCROLL, MAKELONG(nSBCode,0), NULL );
}
}
//---------------------------------------------------------------------------
void THelpPanel::SetMode( int iMode )
{
if( iMode>4 )
return;
if( m_iMode != iMode ){
SaveFirstRow();
if( iMode==0 || iMode==3){
m_nTopBound = 15;
}
else if( iMode==2 ){
m_nTopBound = 60;
}
else{
m_nTopBound = 160;
}
m_nRowShow = (ClientHeight - m_nTopBound - m_nBottomBound) / m_nRowHight;
m_iMode = iMode;
RefreshTextLines();
CalcViewArea();
Invalidate();
}
if( m_pQRPanelAndroid )
m_pQRPanelAndroid->Visible = m_iMode==4;
if( m_pQRPaneliOS )
m_pQRPaneliOS->Visible = m_iMode==4;
for( int i=0; i<SOFTWARE_NUM; i++ ){
if( m_aLblSWName[i] )
m_aLblSWName[i]->Visible = m_iMode==4;
if( m_aLblSWLink[i] )
m_aLblSWLink[i]->Visible = m_iMode==4;
}
m_lblCoinPage->Visible = m_iMode==3;
}
//---------------------------------------------------------------------------
void THelpPanel::RefreshTextLines()
{
int i;
//清空列表
for( i=0; i<m_lstLines.size(); i++ ){
delete m_lstLines[i];
}
m_lstLines.clear();
//读取字符串
int idUser = g_bLogon ? g_infoUser.accountInfo.ID : 0;
int num = 0;
if( m_iMode==0 )
f_CS_GetQnA( num, NULL, false, 0 );
else if( m_iMode==1 )
f_CS_GetQnA( num, NULL, true, idUser );
else if( m_iMode==2 && idUser )
f_CS_GetNotice( num, NULL, idUser );
else if(m_iMode == 3)
ReadData();
if( num>0 ){
TSTRINGPAIR* arrString = new TSTRINGPAIR[num];
bool bRevert = true;
if( m_iMode==0 ){
f_CS_GetQnA( num, arrString, false, 0 );
bRevert = false;
}
else if( m_iMode==1 )
f_CS_GetQnA( num, arrString, true, idUser );
else if( m_iMode==2 )
f_CS_GetNotice( num, arrString, idUser );
for( i=(bRevert?num-1:0); bRevert?i>=0:i<num; bRevert?i--:i++ ){
//处理提问
wstring strQ = str2wstr( UTF8ToMBCS( arrString[i].str1 ) );
TLineString * pLine = new TLineString;
pLine->flag = 1; //question
int nWidth = 0;
int iStart = 0;
for(int j=0; j<strQ.size(); j++ ){
nWidth += Canvas->TextWidth( strQ[j] );
if( nWidth>=m_nRowWidth || strQ[j]=='\n' ){
pLine->strText = strQ.substr( iStart, j-iStart );
if( strQ[j]=='\n' ) j++;
iStart = j;
nWidth = 0;
m_lstLines.push_back( pLine );
if( iStart<strQ.size() ){
pLine = new TLineString;
}
}
}
if( iStart<strQ.size() ){
pLine->strText = strQ.substr( iStart, strQ.size()-iStart );
m_lstLines.push_back( pLine );
}
wstring strA;
if( m_iMode==2 ){
AnsiString strSpace= L"&nbsp;";
AnsiString anStr = arrString[i].str2;
int pos = 0;
while( pos = anStr.Pos( strSpace ) ){
anStr.Delete( pos, strSpace.Length() );
anStr.Insert( L" ", pos );
}
strA = str2wstr( UTF8ToMBCS( anStr.c_str() ) );
}
else{
strA = str2wstr( UTF8ToMBCS( arrString[i].str2 ) );
}
pLine = new TLineString;
pLine->flag = 2; //answer
if( strA.size()>0 ){
nWidth = 0;
iStart = 0;
for(int j=0; j<strA.size(); j++ ){
nWidth += Canvas->TextWidth( strA[j] );
if( nWidth>=m_nRowWidth || strA[j]=='\n' ){
pLine->strText = strA.substr( iStart, j-iStart );
if( strA[j]=='\n' ) j++;
iStart = j;
nWidth = 0;
m_lstLines.push_back( pLine );
if( iStart<strA.size() ){
pLine = new TLineString;
}
}
}
if( iStart<strA.size() ){
pLine->strText = strA.substr( iStart, strA.size()-iStart );
m_lstLines.push_back( pLine );
}
}
else{
if( m_iMode==2 ){
pLine->strText = L"无";
}
else{
pLine->strText = L"暂时还没有答复";
}
m_lstLines.push_back( pLine );
}
if( bRevert ? i>0 : i<num-1 ){ //break
pLine = new TLineString;
m_lstLines.push_back( pLine );
}
}
delete[] arrString;
}
}
//---------------------------------------------------------------------------
void THelpPanel::AddFeedback( wstring str )
{
RefreshTextLines();
m_nBeginShowRow = 0;
CalcViewArea();
Invalidate();
}
//---------------------------------------------------------------------------
void THelpPanel::SaveFirstRow()
{
int iFirstRow = m_nBeginShowRow;
int iFirstTitle = 0;
for( int i=0; i<m_lstLines.size() && i<=iFirstRow; i++ ){
if( m_lstLines[i]->strText.empty() ){
iFirstTitle++;
}
}
m_aFirstRow[m_iMode] = iFirstRow;
m_aFirstTitle[m_iMode] = iFirstTitle;
}
//---------------------------------------------------------------------------
void THelpPanel::ReadData()
{
String str = L"@说明:\n 唱作音符是唱作网的虚拟货币,在唱作魔方软件使用中会\
用到唱作音符。\n@获取途径:\n 唱作音符主要来源于直接充值兑换,在唱作网的\
活动中也可获取。\n 另外,注册用户时也会赠予一定音符。\n";
//String(m_CharBuf);
wchar_t *data = str.c_str();
TLineString *pLine = new TLineString;
int nWidth = 0;
int iStart = 0;
for(int i = 0; i < str.Length(); i++)
{
nWidth += Canvas->TextWidth(String(data[i]));
if( nWidth >= m_nRowWidth || data[i] == '\n' ){
if(data[iStart] == L'@'){
pLine->strText = (str.SubString(iStart + 2, i - iStart + 1)).c_str();
pLine->flag = 3;
}
else{
pLine->flag = 4;
pLine->strText = (str.SubString(iStart + 1, i - iStart + 1)).c_str();
}
if(data[i] == '\n'){
i++;
}
iStart = i;
nWidth = 0;
m_lstLines.push_back(pLine);
pLine = new TLineString;
}
}
pLine->strText = (str.SubString(iStart, str.Length() - iStart + 1)).c_str();
pLine->flag = 4;
m_lstLines.push_back(pLine);
m_lblCoinPage->Top = m_nTopBound + ( m_lstLines.size() + 1 ) * m_nRowHight;
}
//---------------------------------------------------------------------------
bool THelpPanel::HasScrollBar()
{
return m_sbVert?m_sbVert->Visible:0;
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::LinkClick(TObject *Sender)
{
char strURL[256];
if( m_iMode==4 ){
char strPage[256], os[16];
f_CS_GetWebPageURL( URL_SOFTWARE, strPage );
TLabel* pLabel = (TLabel*)Sender;
switch( pLabel->Tag ){
case 0:
strcpy( os, "pc" );
break;
case 1:
strcpy( os, "android" );
break;
case 2:
strcpy( os, "ios" );
break;
}
sprintf( strURL, "%s?id=2&os=%s", strPage, os );
}
else if( m_iMode==3 ){
f_CS_GetWebPageURL( URL_COINSPEC, strURL );
}
ShellExecute(Handle, NULL, ((String)strURL).c_str(), NULL, NULL, SW_SHOWNORMAL);
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::LinkMouseEnter(TObject *Sender)
{
((TLabel*)Sender)->Font->Color = clrEnter;
Screen->Cursor = crHandPoint;
}
//---------------------------------------------------------------------------
void __fastcall THelpPanel::LinkMouseLeave(TObject *Sender)
{
((TLabel*)Sender)->Font->Color = clrLeave;
Screen->Cursor = crDefault;
}
//---------------------------------------------------------------------------