overwriting CHARFORMAT2 struct with EM_GETCHARFORMAT result seems to destroy it, no formatting is shown

StackOverflow https://stackoverflow.com/questions/15536031

Creating fresh CHARFORMAT2W and playing with it goes without issue but then overwriting it with formatting from richedit control seems to damage the structure so it cannot be applied back. But no error is produced.

#include <iostream>
#include <windows.h>
#include <richedit.h>

int main() {
  using namespace std;
  LoadLibrary("Msftedit.dll");
  HWND richeditWindow = CreateWindowExW (
    WS_EX_TOPMOST,
    L"RICHEDIT50W", 
    L"window text",
    WS_SYSMENU | WS_VSCROLL | ES_MULTILINE | ES_NOHIDESEL | WS_VISIBLE,
    50, 50, 500, 500,
    NULL, NULL, NULL, NULL
  );


  GETTEXTLENGTHEX gtl;
  gtl.flags = GTL_NUMCHARS;
  gtl.codepage = 1200;
  int text_len = SendMessageW(richeditWindow, EM_GETTEXTLENGTHEX, (WPARAM)&gtl, (LPARAM)NULL);
  CHARRANGE cr = {text_len,text_len};
  SendMessageW(richeditWindow, EM_EXSETSEL, 0, (LPARAM)&cr);
  static CHARFORMAT2W cf;
  memset( &cf, 0, sizeof cf );
  cf.cbSize = sizeof cf;
  cf.dwMask = CFM_COLOR | CFM_BACKCOLOR;
  SetLastError(0);
  // disabling this line causes text to be colored
  SendMessageW(richeditWindow, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  if (GetLastError()) {
    printf("EM_GETCHARFORMAT failed: %ld", GetLastError());
  }
  cf.crTextColor = RGB(255,0,0);
  cf.crBackColor = RGB(233,233,0);
  if (!SendMessageW(richeditWindow, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf)) {
    printf("EM_SETCHARFORMAT failed: %ld", GetLastError());
  }
  SendMessageW(richeditWindow, EM_REPLACESEL, FALSE, (LPARAM) L"... some more text, should be colored");


  MSG msg;
  while( GetMessageW( &msg, richeditWindow, 0, 0 ) ) {
    TranslateMessage(&msg);
    DispatchMessageW(&msg);
  }
}
有帮助吗?

解决方案

You've misinterpreted how EM_GETCHARFORMAT works. It does not respond to the value of dwMask in the struct that you pass. Instead it fills out as much of the struct as it can. The documentation says:

The dwMask member specifies which attributes are consistent throughout the entire selection.

What this means is that the rich edit control will assign to dwMask as value that specifies which attributes are consistent.

So, you need to completely re-initialize the struct before you make the subsequent call to EM_SETCHARFORMAT.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top