void ScreenObject::Shadow(bool Full) { if (Flags.Check(FSCROBJ_VISIBLE)) { if(Full) { if (!ShadowSaveScr) ShadowSaveScr=new SaveScreen(0,0,ScrX,ScrY); MakeShadow(0,0,ScrX,ScrY); } else { if (!ShadowSaveScr) ShadowSaveScr=new SaveScreen(X1,Y1,X2+2,Y2+1); MakeShadow(X1+2,Y2+1,X2+1,Y2+1); MakeShadow(X2+1,Y1+1,X2+2,Y2+1); } } }
void CWndShadow::Update(HWND hParent) { //int ShadSize = 5; //int Multi = 100 / ShadSize; RECT WndRect; GetWindowRect(hParent, &WndRect); int nShadWndWid = WndRect.right - WndRect.left + m_nSize * 2; int nShadWndHei = WndRect.bottom - WndRect.top + m_nSize * 2; // Create the alpha blending bitmap BITMAPINFO bmi; // bitmap header ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = nShadWndWid; bmi.bmiHeader.biHeight = nShadWndHei; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; // four 8-bit components bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = nShadWndWid * nShadWndHei * 4; BYTE *pvBits; // pointer to DIB section HBITMAP hbitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pvBits, NULL, 0); ZeroMemory(pvBits, bmi.bmiHeader.biSizeImage); MakeShadow((UINT32 *)pvBits, hParent, &WndRect); HDC hMemDC = CreateCompatibleDC(NULL); HBITMAP hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap); POINT ptDst = { WndRect.left + m_nxOffset - m_nSize, WndRect.top + m_nyOffset - m_nSize }; POINT ptSrc = { 0, 0 }; SIZE WndSize = { nShadWndWid, nShadWndHei }; BLENDFUNCTION blendPixelFunction = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; MoveWindow(m_hWnd, ptDst.x, ptDst.y, nShadWndWid, nShadWndHei, FALSE); BOOL bRet = s_UpdateLayeredWindow(m_hWnd, NULL, &ptDst, &WndSize, hMemDC, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); _ASSERT(bRet); // something was wrong.... // Delete used resources SelectObject(hMemDC, hOriBmp); DeleteObject(hbitmap); DeleteDC(hMemDC); }
MAS::Cursor& MAS::Cursor::Create(const Bitmap &bmp, int n) { int i; Destroy(); frameCount = n; for (i=0; i<n; i++) { Bitmap *newBmp = new Bitmap(Size(bmp.w()/n, bmp.h())); bmp.PlainBlit(*newBmp, Point(i*bmp.w()/n,0), Point(0,0), Size(bmp.w()/n,bmp.h())); sprite.push_back(newBmp); } MakeShadow(); return *this; }
void CWndShadow::Update(HWND hParent) { //int ShadSize = 5; //int Multi = 100 / ShadSize; RECT WndRect; GetWindowRect(hParent, &WndRect); int nShadWndWid = 0; int nShadWndHei = 0; if(m_pShadowImage != NULL) { // 九宫格方式,计算阴影窗口总的宽度和高度 nShadWndWid = WndRect.right - WndRect.left + m_nShadowWLT + m_nShadowWRB; nShadWndHei = WndRect.bottom - WndRect.top + m_nShadowHLT + m_nShadowHRB; }else { // 算法阴影方式,计算阴影窗口总的宽度和高度 nShadWndWid = WndRect.right - WndRect.left + m_nSize * 2; nShadWndHei = WndRect.bottom - WndRect.top + m_nSize * 2; } // Create the alpha blending bitmap BITMAPINFO bmi; // bitmap header ZeroMemory(&bmi, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = nShadWndWid; bmi.bmiHeader.biHeight = nShadWndHei; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; // four 8-bit components bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = nShadWndWid * nShadWndHei * 4; BYTE *pvBits; // pointer to DIB section HBITMAP hbitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pvBits, NULL, 0); HDC hMemDC = CreateCompatibleDC(NULL); HBITMAP hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap); if(m_pShadowImage != NULL) { // 九宫格方式画阴影图片 Graphics graphics(hMemDC); CRect rcTemp(0, 0, nShadWndWid, nShadWndHei); DrawImageFrameMID(graphics, m_pShadowImage, rcTemp, 0, 0, m_pShadowImage->GetWidth(), m_pShadowImage->GetHeight(), m_nShadowWLT, m_nShadowHLT, m_nShadowWRB+1, m_nShadowHRB+1); }else { // 画算法阴影 ZeroMemory(pvBits, bmi.bmiHeader.biSizeImage); MakeShadow((UINT32 *)pvBits, hParent, &WndRect); } // 计算阴影窗口偏移位置 POINT ptDst; if(m_pShadowImage != NULL) { ptDst.x = WndRect.left - m_nShadowWLT; ptDst.y = WndRect.top - m_nShadowHLT; } else { ptDst.x = WndRect.left + m_nxOffset - m_nSize; ptDst.y = WndRect.top + m_nyOffset - m_nSize; } POINT ptSrc = {0, 0}; SIZE WndSize = {nShadWndWid, nShadWndHei}; BLENDFUNCTION blendPixelFunction= { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; MoveWindow(m_hWnd, ptDst.x, ptDst.y, nShadWndWid, nShadWndHei, FALSE); BOOL bRet= s_UpdateLayeredWindow(m_hWnd, NULL, &ptDst, &WndSize, hMemDC, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); _ASSERT(bRet); // something was wrong.... // Delete used resources SelectObject(hMemDC, hOriBmp); DeleteObject(hbitmap); DeleteDC(hMemDC); }
int Message( DWORD Flags, size_t Buttons, const wchar_t *Title, const wchar_t * const *Items, size_t ItemsNumber, Plugin* PluginNumber, const GUID* Id ) { string strTempStr; string strClipText; int X1,Y1,X2,Y2; int Length, BtnLength; DWORD I, MaxLength, StrCount; BOOL ErrorSets=FALSE; const wchar_t **Str; wchar_t *PtrStr; const wchar_t *CPtrStr; string strErrStr; IsWarningStyle = (Flags&MSG_WARNING) != 0; IsErrorType = (Flags&MSG_ERRORTYPE) != 0; if(IsErrorType) { LastError = GetLastError(); NtStatus = ifn.RtlGetLastNtStatus(); ErrorSets = GetErrorString(strErrStr); } #if 1 // try to replace inserts if (Items && 0 != (Flags & MSG_INSERT_STRINGS)) { string str_err(strErrStr); DWORD insert_mask = 0; size_t len = strErrStr.GetLength(), pos = 0, inserts_n = 0, inserts[10]; for (size_t i = 1; i <= ItemsNumber-Buttons; ++i) { if (0 != (Flags & MSG_INSERT_STR(i))) { inserts[inserts_n++] = i; if (inserts_n >= ARRAYSIZE(inserts)) break; } } while (str_err.Pos(pos, L"%", pos)) { if (pos >= len-1) break; if (str_err.At(pos+1) >= L'1' && str_err.At(pos+1) <= L'9') { size_t insert_i = 0, pos1 = pos+1; while (pos1 < len && str_err.At(pos1) >= L'0' && str_err.At(pos1) <= L'9') { insert_i = 10*insert_i + str_err.At(pos1) - L'0'; ++pos1; } if (insert_i >= 1 && insert_i <= inserts_n) { insert_mask |= MSG_INSERT_STR(inserts[insert_i-1]); const wchar_t *replacement = Items[inserts[insert_i-1]-1]; str_err.Replace(pos,pos1-pos,replacement); len += wcslen(replacement) - (pos1-pos); pos += wcslen(replacement) - (pos1-pos); } else pos = pos1; } else if (str_err.At(pos+1) == L'%') // "%%" pos += 2; else ++pos; } if (insert_mask == (Flags & MSG_INSERT_STRINGS)) strErrStr = str_err; } #endif // выделим пам¤ть под рабочий массив указателей на строки (+запас 16) Str=(const wchar_t **)xf_malloc((ItemsNumber+ADDSPACEFORPSTRFORMESSAGE) * sizeof(wchar_t*)); if (!Str) return -1; StrCount=static_cast<DWORD>(ItemsNumber-Buttons); // предварительный обсчет максимального размера. for (BtnLength=0,I=0; I<static_cast<DWORD>(Buttons); I++) //?? { BtnLength+=HiStrlen(Items[I+StrCount])+2+2+1; // "[ ", " ]", " " } if(BtnLength) { BtnLength--; } DWORD MAX_WIDTH_MESSAGE = Max(ScrX-1-5-5, BtnLength); for (MaxLength=BtnLength,I=0; I<StrCount; I++) { if (static_cast<DWORD>(Length=StrLength(Items[I]))>MaxLength) MaxLength=Length; } // учтем размер заголовка if (Title && *Title) { I=(DWORD)StrLength(Title)+2; if (MaxLength < I) MaxLength=I; strClipText.Append(Title).Append(L"\r\n\r\n"); } // перва¤ коррекци¤ максимального размера MaxLength = Min(MaxLength, MAX_WIDTH_MESSAGE); // теперь обработаем MSG_ERRORTYPE DWORD CountErrorLine=0; if ((Flags & MSG_ERRORTYPE) && ErrorSets) { strClipText.Append(strErrStr).Append(L"\r\n"); // подсчет количества строк во врапенном сообщениеи ++CountErrorLine; //InsertQuote(ErrStr); // оквочим // вычисление "красивого" размера DWORD LenErrStr=(DWORD)strErrStr.GetLength(); if (LenErrStr > MAX_WIDTH_MESSAGE) { // половина меньше? if (LenErrStr/2 < MAX_WIDTH_MESSAGE) { // а половина + 1/3? if ((LenErrStr+LenErrStr/3)/2 < MAX_WIDTH_MESSAGE) LenErrStr=(LenErrStr+LenErrStr/3)/2; else LenErrStr/=2; } else LenErrStr=MAX_WIDTH_MESSAGE; } MaxLength = Max(MaxLength, LenErrStr); // а теперь проврапим FarFormatText(strErrStr,LenErrStr,strErrStr,L"\n",0); //?? MaxLength ?? PtrStr = strErrStr.GetBuffer(); //BUGBUG: string не предназначен дл¤ хранени¤ строк разделЄнных \0 while ((PtrStr=wcschr(PtrStr,L'\n')) ) { *PtrStr++=0; if (*PtrStr) CountErrorLine++; } strErrStr.ReleaseBuffer(); if (CountErrorLine > ADDSPACEFORPSTRFORMESSAGE) CountErrorLine=ADDSPACEFORPSTRFORMESSAGE; //?? } //BUGBUG: string не предназначен дл¤ хранени¤ строк разделЄнных \0 // заполн¤ем массив... CPtrStr=strErrStr; for (I=0; I < CountErrorLine; I++) { Str[I]=CPtrStr; CPtrStr+=StrLength(CPtrStr)+1; if (!*CPtrStr) // два идущих подр¤д нул¤ - "хандец" всему { ++I; break; } } bool EmptyText=false; if(ItemsNumber==Buttons && !I) { EmptyText=true; Str[I]=L""; I++; StrCount++; ItemsNumber++; } for (size_t J=0; J < ItemsNumber-(EmptyText?1:0); ++J, ++I) { Str[I]=Items[J]; } for (size_t i = 0; i < ItemsNumber-Buttons; ++i) { strClipText.Append(Items[i]).Append(L"\r\n"); } strClipText.Append(L"\r\n"); for (size_t i = ItemsNumber-Buttons; i < ItemsNumber; ++i) { if(i > ItemsNumber-Buttons) { strClipText.Append(L' '); } strClipText.Append(Items[i]); } StrCount+=CountErrorLine; MessageX1=X1=(int(ScrX-MaxLength))/2-4; MessageX2=X2=X1+MaxLength+9; Y1=(ScrY-static_cast<int>(StrCount))/2-2; if (Y1 < 0) Y1=0; MessageY1=Y1; MessageY2=Y2=Y1+StrCount+3; string strHelpTopic(strMsgHelpTopic); strMsgHelpTopic.Clear(); // *** ¬ариант с ƒиалогом *** if (Buttons>0) { size_t ItemCount=StrCount+Buttons+1; DialogItemEx *PtrMsgDlg; DialogItemEx *MsgDlg = new DialogItemEx[ItemCount+1]; if (!MsgDlg) { xf_free(Str); return -1; } for (DWORD i=0; i<ItemCount+1; i++) MsgDlg[i].Clear(); int RetCode; MessageY2=++Y2; MsgDlg[0].Type=DI_DOUBLEBOX; MsgDlg[0].X1=3; MsgDlg[0].Y1=1; MsgDlg[0].X2=X2-X1-3; MsgDlg[0].Y2=Y2-Y1-1; if (Title && *Title) MsgDlg[0].strData = Title; FARDIALOGITEMTYPES TypeItem=DI_TEXT; unsigned __int64 FlagsItem=DIF_SHOWAMPERSAND; BOOL IsButton=FALSE; int CurItem=0; bool StrSeparator=false; bool Separator=false; for (PtrMsgDlg=MsgDlg+1,I=1; I < ItemCount; ++I, ++PtrMsgDlg, ++CurItem) { if (I==StrCount+1 && !StrSeparator && !Separator) { PtrMsgDlg->Type=DI_TEXT; PtrMsgDlg->Flags=DIF_SEPARATOR; PtrMsgDlg->Y1=PtrMsgDlg->Y2=I+1; CurItem--; I--; Separator=true; continue; } if(I==StrCount+1) { TypeItem=DI_BUTTON; FlagsItem=DIF_CENTERGROUP|DIF_DEFAULTBUTTON|DIF_FOCUS; IsButton=TRUE; FirstButtonIndex=CurItem+1; LastButtonIndex=CurItem; } else { FlagsItem&=~DIF_DEFAULTBUTTON; } PtrMsgDlg->Type=TypeItem; PtrMsgDlg->Flags|=FlagsItem; CPtrStr=Str[CurItem]; if (IsButton) { PtrMsgDlg->Y1=Y2-Y1-2+(Separator?1:0); PtrMsgDlg->strData+=CPtrStr; LastButtonIndex++; } else { PtrMsgDlg->X1=(Flags & MSG_LEFTALIGN)?5:-1; PtrMsgDlg->Y1=I+1; wchar_t Chr=*CPtrStr; if (Chr == L'\1' || Chr == L'\2') { CPtrStr++; PtrMsgDlg->Flags|=(Chr==2?DIF_SEPARATOR2:DIF_SEPARATOR); if(I==StrCount) { StrSeparator=true; } } else { if (StrLength(CPtrStr)>X2-X1-9) { PtrMsgDlg->Type=DI_EDIT; PtrMsgDlg->Flags|=DIF_READONLY|DIF_BTNNOCLOSE|DIF_SELECTONENTRY; PtrMsgDlg->X1=5; PtrMsgDlg->X2=X2-X1-5; PtrMsgDlg->strData=CPtrStr; } else { //xstrncpy(PtrMsgDlg->Data,CPtrStr,Min((int)MAX_WIDTH_MESSAGE,(int)sizeof(PtrMsgDlg->Data))); //?? ScrX-15 ?? PtrMsgDlg->strData = CPtrStr; //BUGBUG, wrong len } } } } { if(Separator) { FirstButtonIndex++; LastButtonIndex++; MessageY2++; Y2++; MsgDlg[0].Y2++; ItemCount++; } Dialog Dlg(MsgDlg,ItemCount,MsgDlgProc, &strClipText); if (X1 == -1) X1 = 0; if (Y1 == -1) Y1 = 0; Dlg.SetPosition(X1,Y1,X2,Y2); if(Id) Dlg.SetId(*Id); if (!strHelpTopic.IsEmpty()) Dlg.SetHelp(strHelpTopic); Dlg.SetPluginOwner(reinterpret_cast<Plugin*>(PluginNumber)); // «апомним номер плагина if (IsWarningStyle) { Dlg.SetDialogMode(DMODE_WARNINGSTYLE); } Dlg.SetDialogMode(DMODE_MSGINTERNAL); if (Flags & MSG_NOPLUGINS) Dlg.SetDialogMode(DMODE_NOPLUGINS); FlushInputBuffer(); if (Flags & MSG_KILLSAVESCREEN) SendDlgMessage((HANDLE)&Dlg,DM_KILLSAVESCREEN,0,0); Dlg.Process(); RetCode=Dlg.GetExitCode(); } delete [] MsgDlg; xf_free(Str); return(RetCode<0?RetCode:RetCode-StrCount-1-(Separator?1:0)); } // *** Ѕез ƒиалога! *** SetCursorType(0,0); if (!(Flags & MSG_KEEPBACKGROUND)) { SetScreen(X1,Y1,X2,Y2,L' ',ColorIndexToColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT)); MakeShadow(X1+2,Y2+1,X2+2,Y2+1); MakeShadow(X2+1,Y1+1,X2+2,Y2+1); Box(X1+3,Y1+1,X2-3,Y2-1,ColorIndexToColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX),DOUBLE_BOX); } SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT); if (Title && *Title) { string strTempTitle = Title; if (strTempTitle.GetLength() > MaxLength) strTempTitle.SetLength(MaxLength); GotoXY(X1+(X2-X1-1-(int)strTempTitle.GetLength())/2,Y1+1); FS<<L" "<<strTempTitle<<L" "; } for (I=0; I<StrCount; I++) { CPtrStr=Str[I]; wchar_t Chr=*CPtrStr; if (Chr == 1 || Chr == 2) { Length=X2-X1-5; if (Length>1) { SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX); GotoXY(X1+3,Y1+I+2); DrawLine(Length,(Chr == 2?3:1)); CPtrStr++; int TextLength=StrLength(CPtrStr); if (TextLength<Length) { GotoXY(X1+3+(Length-TextLength)/2,Y1+I+2); Text(CPtrStr); } SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGTEXT); } continue; } if ((Length=StrLength(CPtrStr))>ScrX-15) Length=ScrX-15; int Width=X2-X1+1; wchar_t *lpwszTemp = nullptr; int PosX; if (Flags & MSG_LEFTALIGN) { lpwszTemp = (wchar_t*)xf_malloc((Width-10+1)*sizeof(wchar_t)); _snwprintf(lpwszTemp,Width-10+1,L"%.*s",Width-10,CPtrStr); GotoXY(X1+5,Y1+I+2); } else { PosX=X1+(Width-Length)/2; lpwszTemp = (wchar_t*)xf_malloc((PosX-X1-4+Length+X2-PosX-Length-3+1)*sizeof(wchar_t)); _snwprintf(lpwszTemp,PosX-X1-4+Length+X2-PosX-Length-3+1,L"%*s%.*s%*s",PosX-X1-4,L"",Length,CPtrStr,X2-PosX-Length-3,L""); GotoXY(X1+4,Y1+I+2); } Text(lpwszTemp); xf_free(lpwszTemp); } /* $ 13.01.2003 IS - ѕринудительно уберем запрет отрисовки экрана, если количество кнопок в сообщении равно нулю и макрос закончил выполн¤тьс¤. Ёто необходимо, чтобы заработал прогресс-бар от плагина, который был запущен при помощи макроса запретом отрисовки (bugz#533). */ xf_free(Str); if (!Buttons) { if (ScrBuf.GetLockCount()>0 && !CtrlObject->Macro.PeekKey()) ScrBuf.SetLockCount(0); ScrBuf.Flush(); } return 0; }
int Message( DWORD Flags, int Buttons, const wchar_t *Title, const wchar_t * const *Items, int ItemsNumber, INT_PTR PluginNumber ) { FARString strTempStr; int X1,Y1,X2,Y2; int Length, BtnLength, J; DWORD I, MaxLength, StrCount; BOOL ErrorSets=FALSE; const wchar_t **Str; wchar_t *PtrStr; const wchar_t *CPtrStr; FARString strErrStr; if (Flags & MSG_ERRORTYPE) ErrorSets = GetErrorString(strErrStr); // выделим память под рабочий массив указателей на строки (+запас 16) Str=(const wchar_t **)xf_malloc((ItemsNumber+ADDSPACEFORPSTRFORMESSAGE) * sizeof(wchar_t*)); if (!Str) return -1; StrCount=ItemsNumber-Buttons; // предварительный обсчет максимального размера. for (BtnLength=0,I=0; I<static_cast<DWORD>(Buttons); I++) //?? { BtnLength+=HiStrlen(Items[I+StrCount])+2+2+1; // "[ ", " ]", " " } if(BtnLength) { BtnLength--; } for (MaxLength=BtnLength,I=0; I<StrCount; I++) { if (static_cast<DWORD>(Length=StrLength(Items[I]))>MaxLength) MaxLength=Length; } // учтем так же размер заголовка if (Title && *Title) { I=(DWORD)StrLength(Title)+2; if (MaxLength < I) MaxLength=I; } // певая коррекция максимального размера if (MaxLength > MAX_WIDTH_MESSAGE) MaxLength=MAX_WIDTH_MESSAGE; // теперь обработаем MSG_ERRORTYPE DWORD CountErrorLine=0; if ((Flags & MSG_ERRORTYPE) && ErrorSets) { // подсчет количества строк во врапенном сообщениеи ++CountErrorLine; //InsertQuote(ErrStr); // оквочим // вычисление "красивого" размера DWORD LenErrStr=(DWORD)strErrStr.GetLength(); if (LenErrStr > MAX_WIDTH_MESSAGE) { // половина меньше? if (LenErrStr/2 < MAX_WIDTH_MESSAGE) { // а половина + 1/3? if ((LenErrStr+LenErrStr/3)/2 < MAX_WIDTH_MESSAGE) LenErrStr=(LenErrStr+LenErrStr/3)/2; else LenErrStr/=2; } else LenErrStr=MAX_WIDTH_MESSAGE; } else if (LenErrStr < MaxLength) LenErrStr=MaxLength; if (MaxLength > LenErrStr && MaxLength >= MAX_WIDTH_MESSAGE) MaxLength=LenErrStr; if (MaxLength < LenErrStr && LenErrStr <= MAX_WIDTH_MESSAGE) MaxLength=LenErrStr; // а теперь проврапим //PtrStr=FarFormatText(ErrStr,MaxLength-(MaxLength > MAX_WIDTH_MESSAGE/2?1:0),ErrStr,sizeof(ErrStr),"\n",0); //?? MaxLength ?? FarFormatText(strErrStr,LenErrStr,strErrStr,L"\n",0); //?? MaxLength ?? PtrStr = strErrStr.GetBuffer(); //BUGBUG: FARString не преднозначен для хранения строк разделённых \0 while ((PtrStr=wcschr(PtrStr,L'\n')) ) { *PtrStr++=0; if (*PtrStr) CountErrorLine++; } strErrStr.ReleaseBuffer(); if (CountErrorLine > ADDSPACEFORPSTRFORMESSAGE) CountErrorLine=ADDSPACEFORPSTRFORMESSAGE; //?? } //BUGBUG: FARString не преднозначен для хранения строк разделённых \0 // заполняем массив... CPtrStr=strErrStr; for (I=0; I < CountErrorLine; I++) { Str[I]=CPtrStr; CPtrStr+=StrLength(CPtrStr)+1; if (!*CPtrStr) // два идущих подряд нуля - "хандец" всему { ++I; break; } } bool EmptyText=false; if(ItemsNumber==Buttons && !I) { EmptyText=true; Str[I]=L""; I++; StrCount++; ItemsNumber++; } for (J=0; J < ItemsNumber-(EmptyText?1:0); ++J, ++I) { Str[I]=Items[J]; } StrCount+=CountErrorLine; MessageX1=X1=(ScrX-MaxLength)/2-4; MessageX2=X2=X1+MaxLength+9; Y1=(ScrY-StrCount)/2-2; if (Y1 < 0) Y1=0; MessageY1=Y1; MessageY2=Y2=Y1+StrCount+3; FARString strHelpTopic(strMsgHelpTopic); strMsgHelpTopic.Clear(); // *** Вариант с Диалогом *** if (Buttons>0) { DWORD ItemCount=StrCount+Buttons+1; DialogItemEx *PtrMsgDlg; DialogItemEx *MsgDlg = new(std::nothrow) DialogItemEx[ItemCount+1]; if (!MsgDlg) { xf_free(Str); return -1; } for (DWORD i=0; i<ItemCount+1; i++) MsgDlg[i].Clear(); int RetCode; MessageY2=++Y2; MsgDlg[0].Type=DI_DOUBLEBOX; MsgDlg[0].X1=3; MsgDlg[0].Y1=1; MsgDlg[0].X2=X2-X1-3; MsgDlg[0].Y2=Y2-Y1-1; if (Title && *Title) MsgDlg[0].strData = Title; int TypeItem=DI_TEXT; DWORD FlagsItem=DIF_SHOWAMPERSAND; BOOL IsButton=FALSE; int CurItem=0; bool StrSeparator=false; bool Separator=false; for (PtrMsgDlg=MsgDlg+1,I=1; I < ItemCount; ++I, ++PtrMsgDlg, ++CurItem) { if (I==StrCount+1 && !StrSeparator && !Separator) { PtrMsgDlg->Type=DI_TEXT; PtrMsgDlg->Flags=DIF_SEPARATOR; PtrMsgDlg->Y1=PtrMsgDlg->Y2=I+1; CurItem--; I--; Separator=true; continue; } if(I==StrCount+1) { PtrMsgDlg->DefaultButton=TRUE; PtrMsgDlg->Focus=TRUE; TypeItem=DI_BUTTON; FlagsItem=DIF_CENTERGROUP; IsButton=TRUE; FirstButtonIndex=CurItem+1; LastButtonIndex=CurItem; } PtrMsgDlg->Type=TypeItem; PtrMsgDlg->Flags|=FlagsItem; CPtrStr=Str[CurItem]; if (IsButton) { PtrMsgDlg->Y1=Y2-Y1-2+(Separator?1:0); PtrMsgDlg->strData+=CPtrStr; LastButtonIndex++; } else { PtrMsgDlg->X1=(Flags & MSG_LEFTALIGN)?5:-1; PtrMsgDlg->Y1=I+1; wchar_t Chr=*CPtrStr; if (Chr == L'\1' || Chr == L'\2') { CPtrStr++; PtrMsgDlg->Flags|=(Chr==2?DIF_SEPARATOR2:DIF_SEPARATOR); if(I==StrCount) { StrSeparator=true; } } else if (StrLength(CPtrStr)>X2-X1-9) { PtrMsgDlg->Type=DI_EDIT; PtrMsgDlg->Flags|=DIF_READONLY|DIF_BTNNOCLOSE|DIF_SELECTONENTRY; PtrMsgDlg->X1=5; PtrMsgDlg->X2=X2-X1-5; PtrMsgDlg->strData=CPtrStr; continue; } //xstrncpy(PtrMsgDlg->Data,CPtrStr,Min((int)MAX_WIDTH_MESSAGE,(int)sizeof(PtrMsgDlg->Data))); //?? ScrX-15 ?? PtrMsgDlg->strData = CPtrStr; //BUGBUG, wrong len } } { if(Separator) { FirstButtonIndex++; LastButtonIndex++; MessageY2++; Y2++; MsgDlg[0].Y2++; ItemCount++; } IsWarningStyle=Flags&MSG_WARNING; Dialog Dlg(MsgDlg,ItemCount,MsgDlgProc); Dlg.SetPosition(X1,Y1,X2,Y2); if (!strHelpTopic.IsEmpty()) Dlg.SetHelp(strHelpTopic); Dlg.SetPluginNumber(PluginNumber); // Запомним номер плагина if (IsWarningStyle) { Dlg.SetDialogMode(DMODE_WARNINGSTYLE); } Dlg.SetDialogMode(DMODE_MSGINTERNAL); FlushInputBuffer(); if (Flags & MSG_KILLSAVESCREEN) SendDlgMessage((HANDLE)&Dlg,DM_KILLSAVESCREEN,0,0); Dlg.Process(); RetCode=Dlg.GetExitCode(); } delete [] MsgDlg; xf_free(Str); return(RetCode<0?RetCode:RetCode-StrCount-1-(Separator?1:0)); } // *** Без Диалога! *** SetCursorType(0,0); if (!(Flags & MSG_KEEPBACKGROUND)) { SetScreen(X1,Y1,X2,Y2,L' ',(Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT); MakeShadow(X1+2,Y2+1,X2+2,Y2+1); MakeShadow(X2+1,Y1+1,X2+2,Y2+1); Box(X1+3,Y1+1,X2-3,Y2-1,(Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX,DOUBLE_BOX); } SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGTEXT:COL_DIALOGTEXT); if (Title && *Title) { FARString strTempTitle = Title; if (strTempTitle.GetLength() > MaxLength) strTempTitle.SetLength(MaxLength); GotoXY(X1+(X2-X1-1-(int)strTempTitle.GetLength())/2,Y1+1); FS<<L" "<<strTempTitle<<L" "; } for (I=0; I<StrCount; I++) { int PosX; CPtrStr=Str[I]; wchar_t Chr=*CPtrStr; if (Chr == 1 || Chr == 2) { int Length=X2-X1-5; if (Length>1) { SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGBOX); GotoXY(X1+3,Y1+I+2); DrawLine(Length,(Chr == 2?3:1)); CPtrStr++; int TextLength=StrLength(CPtrStr); if (TextLength<Length) { GotoXY(X1+3+(Length-TextLength)/2,Y1+I+2); Text(CPtrStr); } SetColor((Flags & MSG_WARNING)?COL_WARNDIALOGBOX:COL_DIALOGTEXT); } continue; } if ((Length=StrLength(CPtrStr))>ScrX-15) Length=ScrX-15; int Width=X2-X1+1; wchar_t *lpwszTemp = nullptr; if (Flags & MSG_LEFTALIGN) { lpwszTemp = (wchar_t*)xf_malloc((Width-10+1)*sizeof(wchar_t)); swprintf(lpwszTemp,Width-10+1,L"%.*ls",Width-10,CPtrStr); GotoXY(X1+5,Y1+I+2); } else { PosX=X1+(Width-Length)/2; lpwszTemp = (wchar_t*)xf_malloc((PosX-X1-4+Length+X2-PosX-Length-3+1)*sizeof(wchar_t)); swprintf(lpwszTemp,PosX-X1-4+Length+X2-PosX-Length-3+1,L"%*ls%.*ls%*ls",PosX-X1-4,L"",Length,CPtrStr,X2-PosX-Length-3,L""); GotoXY(X1+4,Y1+I+2); } Text(lpwszTemp); xf_free(lpwszTemp); } /* $ 13.01.2003 IS - Принудительно уберем запрет отрисовки экрана, если количество кнопок в сообщении равно нулю и макрос закончил выполняться. Это необходимо, чтобы заработал прогресс-бар от плагина, который был запущен при помощи макроса запретом отрисовки (bugz#533). */ xf_free(Str); if (!Buttons) { if (ScrBuf.GetLockCount()>0 && !CtrlObject->Macro.PeekKey()) ScrBuf.SetLockCount(0); ScrBuf.Flush(); } return 0; }