Unicode w Edit lub RichEdit

0

To już było, ale nie otrzymałem do tej pory odpowiedzi. Wobec tego przyklejam temat. Pierwsza osoba, która poda mi satysfakcjonujące rozwiązanie (Delphi, BCB, VC, ASM lub dowolne WinAPI) ma u mnie zgrzewkę piwa (lub równowartość). Pytanie brzmi:
Jak w dowolnej kontrolce Edit (lub RichEdit, ale standardowej. Żadne dodatkowe komponenty) wyświetlić znaki w unicode. Przede wszystkim interesują mnie znaki:
ĈĉĜĝĤĥĴĵŜŝŬŭ
o kodach odpowiednio:
108h 109h 11Ch 11Dh 124h 125h 134h 135h 15Ch 15Dh 16Ch 16Dh

I nie interesuje mnie wcale wklejanie. Bo wkleić do RichEdit mogę bez problemu. Mogę też naciskając Ctrl+Shift+Alt+F12 zamienić kod szesnastkowy na znak (i odwrotnie Alt+Shift+X)
Także nie chodzi mi o wyświetlanie wykorzystująć HDC (czyli np. na Canvasie)

Wymagania duże, ale jestem zdesperowany.

0

Czy to co oferują na http://www.delphi-unicode.net/ nie pomaga? Nie mówię o kompilowaniu od razu i dodawaniu bibloteki, tylko o zerżnięciu na żywca odpowiednich funkcji :)

[ Jak przeleciałem przez to, to była tam jakaś funkcja KeyUnicode, ale to może nie to. Szukałbym dalej, ale piwa nie pijam :]

0

Tamtejsze komponenty też już ściągałem i przeglądałem. Problem jest taki, że tam jest napisany całkiem inny komponent z TStrings podmienionym przez TWideStrings i nie da się zastosować tego do istniejącego RichEdit.

0

no to chyba mam zgrzewke piwa :)

tak sie sklada ze wlasnie pisze aplikacje oparta na CRichEdit'ach i musialem sie dzisiaj dostac do danych sformatowanych w postaci RTF. chodzilo mi o prznoszenie ich pomiedzy kolejnymi CRichEdit'ami. po kilkunastu albo wiecej nieudanych probach udalo mi sie wyrwac dane z tej j.b.n.j kotrolki. a jak sie udalo wyciagnac to i analogicznie mozna wlozyc :). stringa ktorego tam wkladam nie wymyslalem i nawet nie mam pojecia do konca co sie tam kryje pod tymi nazwami,po prostu go wyciagnalem z kontrolki po wklejeniu uprzednio tych znaczkow z posta, ale najwazniejsza czesc kryje sie w trzeciej linijce tego stringa.

1.a wiec tak na poczatek musimy przeladowac funkcje EditStreamCallBack(...), lub stworzyc inna o takich samych patrametrach (co oczywiste jest)

[code]
static DWORD CALLBACK MyEditStreamCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CString *pStr = (CString *)dwCookie;

if( pStr->GetLength() < cb )
{
	*pcb = pStr->GetLength();
	memcpy(pbBuff, (LPCSTR)*pStr, *pcb );
	pStr->Empty();
}
else
{
	*pcb = cb;
	memcpy(pbBuff, (LPCSTR)*pStr, *pcb );
	*pStr = pStr->Right( pStr->GetLength() - cb );
}
return 0;

}
[/code]

taka funkcja umozliwi nam wprowadzenie danych za pomoca metody StreamIn(..), wprost ze stringa
2. wlozyc strina z tymi znaczkami do kontrolki
[code]
CString sString= "{\rtf1\ansi\ansicpg1250\deff0\deflang1045{\fonttbl{\f0\froman\fcharset0 Times New Roman;}"
"{\f1\fswiss\fcharset238{\*\fname Arial;}Arial CE;}}\viewkind4\uc1\pard\sb100\sa100\f0\fs24"
"\u264?\u265?\u284?\u285?\u292?\u293?\u308?\u309?\u348?\u349?\u364?\u365?"
"\par\pard\f1\fs20\parn}";

EDITSTREAM es = {(DWORD)&sString, 0, MyEditStreamCallBack};

GetRichEditCtrl().StreamIn(SF_RTF | SFF_SELECTION, es);

[/code]
jak widac te tajemnicze znaczki unikodowe sa zapisane za pomoca \uXXX? gdzie XXX numer zanku w unikodzie

0

Sprawdzałeś to na zwykłym TRichEdit? Domyślam się, że nie. Powiem ci jaki jest problem i jak go należy rozwiązać, bo udało mi się to zrobić już jakiś czas temu (co prawda jedynie w asm).
Otóż problem jest taki, że TRichEdit to kontrolka windowsowa i Delphi domyślnie tworząc projekt używa wersji ANSI wszystkich funkcji i kontrolek. Obsługa unicode jest w WinNT, ale ponieważ domyślnie jest to kontrolka ANSI to kody są automatycznie przez system zamieniane. Nie można więc np. wysłać komunikatu z wartością typlu Unicode, ponieważ tworząc kontrolkę ANSI, musimy takiego samego typu funkcji używać.
Rozwiązaniem jest tworzenie wersji Unicode tej kontrolki. I tak też w asm robiłem.
W Delphi nie bardzo by mi się chciało grzebać w WinAPI, więc zamiast wszystko od początku tworzyć, wystarczy jedynie jeszcze raz utworzyć ten komponent tym razem w wersji Unicode. Wydaje mi się, że chyba gdzieś już pisałem coś takiego. Kod z jednej z kontrolek wyciągnąłem.
Ale dzięki za zainteresowanie. Może spróbuję jakoś twój sposób wykorzystać. Może będzie prościej.
A swoją drogą, ciekwa jestem, kiedy w Delphi będzie wersja kontrolek pod Unicode.

0

sprawdzalem to tylko pod VC i jesli chodzi o inne komplikatory i jezyki to nie mam pojecia czy pojdzie, ale wydaj mi sie ze tak, przeciez interpretacja tego stringa zalezy tylko od wlasciwosci kotrolki. zastanawiam sie tylko dlaczego nie dolozyli tam metody ktora potrafi obslugiwac UTF-8 . to by na pewno ich nic nie kosztowalo duzo roboty a znaczki unikodowe zajmowalyby 4 lub mniej bajtow a nie 5 lub wiecej jak to jest teraz

0

a grzebiac w msdn-e znalazlem taka infomacje
SF_UNICODE - Rich Edit 2.0 and later: Indicates Unicode text. You can combine this flag with the SF_TEXT flag.
niesty RichEdit 2.0 tochyba dla VC++.NET jest wiec nie sprawdze tego ale jak ktos ma dostep do takiej kontroli to móglby sprawdzic
acha info mozna znalezc w msdn w opisie message'u EM_STREAMIN

0

poniewaz jeszcze nikt nie odkleil tego postu to pozwole sobie dodtac kod który <ort>slurzy </ort>do wprowadzanai i wyciagania z kontrolik CRichEdit stringów z formatowanym textem w RTF-ie
[code]
DWORD CALLBACK CMyRichView::FromStringToRich(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
CString *pStr = (CString *)dwCookie;
if( pStr->GetLength() < cb ){
*pcb = pStr->GetLength();
memcpy(pbBuff, (LPCSTR)*pStr, *pcb );
pStr->Empty();
}
else{
*pcb = cb;
memcpy(pbBuff, (LPCSTR)*pStr, *pcb );
*pStr = pStr->Right( pStr->GetLength() - cb );
}
return 0;
}

DWORD CALLBACK CMyRichView::FromRichToString(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
char cLastChar;
CString *pStr = (CString )dwCookie;
cLastChar=
(pbBuff+cb-1);
*(pbBuff+cb-1)=0;
*pStr+=(LPCSTR)pbBuff;
*(pbBuff+cb-1)=cLastChar;
*(pbBuff+cb-1)=0;
*pStr+=cLastChar;
*pcb=cb;
return 0;
}

void CMyRichView::GetRichText(CString& sString,bool bSelected/* =true */)
{
sString.Empty();
EDITSTREAM es = {(DWORD)&sString, 0, FromRichToString};
if(bSelected==true)
GetRichEditCtrl().StreamOut(SF_RTF| SFF_SELECTION , es);
else
GetRichEditCtrl().StreamOut(SF_RTF , es);

}
void CMyRichView::SetRichText(CString sString,bool bSelected/* =true */)
{
EDITSTREAM es = {(DWORD)&sString, 0, FromStringToRich};
if(bSelected==true)
GetRichEditCtrl().StreamIn(SF_RTF| SFF_SELECTION , es);
else
GetRichEditCtrl().StreamIn(SF_RTF , es);

}

[/code]

klasa CMyRichView dziedziczy po CRichEditView

no i kawalek naglówka

static DWORD CALLBACK FromStringToRich(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
static DWORD CALLBACK FromRichToString(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);	

void	GetRichText(CString& sString,bool bSelected=true);
void	SetRichText(CString sString,bool bSelected=true);
0

Ostatnio byłą dyskusja czy odświeżać stare wątki. Ja sam chwilę teraz kombinuje z WinAPI i UNICODE. O ile z WinAPI jakoś sobie starałem dawać radę. O tyle z zastosowaniem UNICODE w swojej aplikacji miałem stycznośc tylko pod VCL i to przy wsparciu się komponentami TNT. Mowa tutaj oczywiście o starszych wersjach Delphi, jak siódemka. Otóż powyższe porady są mało przydatne, a wygooglowałem je. Może tak dawno kiedy były pisany dostęp do MSDN był nadal ograniczony przez pobieranie opłat od Developerów.

Ale jeśli ktoś kiedyś będzie szukał prostego rozwiązania na start. To zgodnie z tym, co napisano przede wszystkim na http://msdn.microsoft.com/en-us/library/windows/desktop/bb775464(v=vs.85).aspx kontrolka na przykład Edit nie moze posiadać stylu ES_OEMCONVERT. Czyli taki kod testowany z Editem z TNT da te same rezultaty w tworzonym Editcie, oczywiście pomijają domyślną czcionkę. Może ktoś się w przyszłości komuś przyda te info, bo będzie googlował jak ja i natrafi podobnie do mnie, na ten wątek. Wiadomo do Edita z TNT można wkleić jakieś egzotyczne znaki jak na przykład 대한민국 z hasła: http://pl.wikipedia.org/wiki/Korea_Południowa :)

procedure SetTextWide(AHwnd : HWND; Text : WideString);
begin
  if AHwnd > 0 then
  begin
    SendMessageW(AHwnd, WM_SETTEXT, 0, integer(PWideChar(Text)));
  end;
end;

procedure TForm1.Button1Click(Sender : TObject);
var
  EditH : HWND;
begin
  EditH := CreateWindowExW(WS_EX_CLIENTEDGE, 'EDIT', '',
    WS_CHILDWINDOW or WS_VISIBLE or WS_TABSTOP or ES_NOHIDESEL or ES_AUTOHSCROLL,
    10, 10, 350, 22, Self.Handle, 0, hInstance, nil);
  SetTextWide(EditH, TntEdit1.Text);
end;
0

Visual 2010 Express

#define _WIN32_WINNT 0x501
#define STRICT
#define UNICODE
#define _UNICODE

#include <Windows.h>
#include <WindowsX.h>
#include <CommCtrl.h>

#pragma comment(lib,"comctl32.lib")

HFONT dlgFont;

HFONT getDialogFont()
{
	NONCLIENTMETRICS ncm = {sizeof(ncm)};
	SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
	return CreateFontIndirect(&ncm.lfMessageFont);
}

BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
	dlgFont = getDialogFont();
	return TRUE;
}

void OnDestroy(HWND hwnd)
{
	DeleteObject(dlgFont);
	PostQuitMessage(0);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uiMsg)
	{
		HANDLE_MSG(hwnd, WM_CREATE, OnCreate);
		HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);
	default:
		return DefWindowProc(hwnd, uiMsg, wParam, lParam);
	}
}

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE, LPSTR, int nShowCmd)
{
	InitCommonControls();

	WNDCLASS wc = {};
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hinst;
	wc.hbrBackground = HBRUSH(COLOR_3DFACE+1);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.lpszClassName = L"Test_class";
	ATOM atom = RegisterClass(&wc);

	HWND hwnd = CreateWindow(
		MAKEINTATOM(atom),
		L"Test",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		CW_USEDEFAULT, nShowCmd,
		400, 300,
		NULL, NULL, hinst, 0);

	HWND edit = CreateWindow(
		WC_EDIT,
		NULL,
		WS_CHILD | WS_VISIBLE | WS_BORDER,
		100, 100,
		100, 20,
		hwnd, NULL, hinst, 0);

	FORWARD_WM_SETFONT(edit, dlgFont, FALSE, SendMessage);

	Edit_SetText(edit, L"\x108\x109\x11C\x11D\x124\x125\x134\x135\x15C\x15D\x16C\x16D");

	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

esperanto.PNG

1 użytkowników online, w tym zalogowanych: 0, gości: 1