Member 12776813 Ответов: 0

Выравнивание текста и столбца не было правильным в приложении при использовании clistctrl при обновлении VC++ 2015


Я обновляю проект приложения VC++6.0 32bit MFC до VC++2015 для развертывания в windows 7. Ниже приведен метод выравнивания текста.

Метод столбцов:
/**** "|" symbol are used as separators ****/

int CListCtrlEx::CreateColumns(LPCSTR fmt, ...)
{
   ClearAll();
   
   char* buffer = new char[strlen(fmt) + 256];
   
   va_list args;
   va_start (args,fmt);
   vsprintf (buffer,fmt,args);
   va_end (args);

   CStringEx cols = buffer;
   int col;
   for( col = 0; col < cols.GetFieldCount("|"); col++ )
      AddColumn(cols.GetField("|", col), col);

   delete [] buffer;

   delete [] m_arrayColumnClicks;
   m_arrayColumnClicks = NULL;
   m_arrayColumnClicks = new int[col];

   int i;
   for( i = 0; i < col; i++)
      m_arrayColumnClicks[i] = 1;

   AutoSizeColumns();

   return i; // return column count
}

int CListCtrlEx::AddColumn(LPCSTR desc, int col, LVCOLUMN* lvc)
{
   if( lvc && lvc->pszText == NULL )
      lvc->pszText = (char*)desc;

   LV_COLUMN t_lvc;

   t_lvc.mask    = lvc ? lvc->mask     : LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
   t_lvc.fmt     = lvc ? lvc->fmt      : LVCFMT_LEFT;
   t_lvc.cx      = lvc ? lvc->cx       : 75; // in pixels
   t_lvc.pszText = lvc ? lvc->pszText  : (char*)desc;

   return InsertColumn(col, &t_lvc);
}

void CListCtrlEx::AutoSizeColumns(int col)
{
//   SetRedraw(FALSE);
   int mincol =   col < 0 ? 0 : col;
   int maxcol =   GetColumnCount();

   for( col = mincol; col < maxcol; col++)
   {
      SetColumnWidth(col, LVSCW_AUTOSIZE);
      int wc1 = GetColumnWidth(col);

      SetColumnWidth(col, LVSCW_AUTOSIZE_USEHEADER);
      int wc2 = GetColumnWidth(col);
      
      int wc = max(wc1, wc2);
      SetColumnWidth(col,wc);
   }

   Invalidate();
}


Приведенный выше код отлично работает с целевой ОС VC++ 6.0 windows xp. Но в VC++2015 он не нацелен на Windows 7.
Хуже всего то, что отладочная версия и версия выпуска показывают различные типы ошибок выравнивания в столбце и тексте.

Что я уже пробовал:

Похоже, это не проблема с кодом.
Есть ли какие-либо связанные с CListCtrl dll-файлы, которые не соответствуют последним версиям? Я включил "legacy_stdio_definitions. lib" в качестве мандата моего проекта ? ОПЕРАЦИОННАЯ
Может быть, переполнение буфера из-за размера бита не совпадает с ранее разработанным проектом в текущей версии ? ОПЕРАЦИОННАЯ
Какие-либо другие предварительные условия должны быть выполнены в настройках ?

Jochen Arndt

Что вы подразумеваете под"ошибкой выравнивания"?

Рендеринг элементов управления списком и шрифтов был изменен начиная с Windows XP, так что получение другого представления на экране является нормальным.

Member 12776813

Не могли бы вы подсказать мне, как исправить эти ошибки рендеринга?
Я должен сделать код мудрым, или добавление каких-либо внешних библиотек поможет.
*Я новичок в VS, не могли бы вы сообщить мне подробности?

Jochen Arndt

Я не могу этого сделать, не зная, как выглядят эти "ошибки".
Было бы также полезно увидеть код вашей функции AutoSizeColumns() и, возможно, код PlaceControls (), если он каким-то образом задействован.

Элемент управления списком рисуется системой. Единственный способ изменить внешний вид - это использовать предоставленные функции API или использовать список собственников (custom draw).

Member 12776813

Добавлены запрошенные функции.
Дисплей выглядит примерно так,
Ожидаемый:
Столбцы Полей
- оба в разных колонках

Актуально в отладочной версии:
Поле / Статус
В версии :
Поле Поле|
-в разных колонках



int CStringEx:: GetFieldCount( LPCTSTR delim )
{
LPTSTR lpsz, lpszRemainder = CA2T(CString:: GetString());
int lenDelim = lstrlen( delim );

int iCount = 1;
while ((lpsz = _tcsstr(lpszRemainder, delim))! = NULL )
{
lpszRemainder = lpsz + lenDelim;
людей icount++;
}

возвращение людей icount;
}

CStringEx CStringEx:: GetField( TCHAR delim, int fieldnum)
{
LPTSTR lpsz, lpszRemainder = CA2T(CString:: GetString ()), lpszret;
int retlen;

while (fieldnum-- >= 0 )
{
lpszret = lpszRemainder;
lpsz = _tcschr(lpszRemainder, (_TUCHAR)delim);
if (lpsz )
{
// Мы действительно нашли делим
retlen = lpsz - lpszRemainder;
lpszRemainder = lpsz + 1;
}
ещё
{
retlen = lstrlen( lpszRemainder );
lpszRemainder += retlen; / / изменить на пустую строку
}
}
return Mid( lpszret - CString:: GetString (), retlen );
}

Это функции, которые заботятся о разделениях строк.

Jochen Arndt

Сначала вы должны исправить свои преобразования ANSI / TCHAR. Опубликованный код даже не должен компилироваться для сборок Unicode:

Здесь вы проходите LPCSTR:
седла.GetFieldCount("|")

Но функция ожидает lpctstr:
int CStringEx:: GetFieldCount( LPCTSTR delim )

Проверить это:
LPTSTR lpszRemainder = CA2T(CString:: GetString());
При сборке Unicode GetString () возвращает LPCWSTR. Рассматривая это как ANSI, возвращает строку с одним символом!

Функция GetField() объявляется как
CStringEx CStringEx:: GetField( TCHAR delim, int fieldnum)

с разделителем TCHAR но вы передаете LPCSTR:
седла.Getfield у("|", коль)

В целом эти функции CStringEx могут быть реализованы гораздо лучше (и использовать один тип разделителя: символ или строку).

Не должно быть даже необходимости делать преобразования ANSI / Unicode внутри этих функций. Просто используйте функции-члены CString и библиотечные функции _tXXX.

Если вам нужно использовать строки ANSI со сборками Unicode, используйте версию ANSI cstringa явно и избегайте этих макросов преобразования ATL.

Member 12776813

Это действительно работает.
Я заменил все строковые типы на char TCHAR и LPTCSTR без преобразования CA2T. Теперь жала правильно выровнены.
Пожалуйста, дайте мне знать, если у вас есть какие-либо дополнительные предложения о том, какой тип предпочтительнее для этого случая.
Большое вам спасибо !!!

Jochen Arndt

Чтобы проверить основные функциональные возможности VC2015 и Win 7, Вы можете настроить проект VC 2015 на использование ANSI / MCBS (как используется VC6) вместо Unicode.

Если вы хотите использовать Unicode, вы должны преобразовать свой код souce, что может быть трудоемкой задачей (в зависимости от размера проекта).
Видишь https://msdn.microsoft.com/en-us/library/cc194801.aspx.

0 Ответов