Formatted text encoding in binary plist - cocoa

I'm trying to do some scripting that edits a binary plist file. The plist describes the objects contained in a DVD studio pro file. It appears that a text box in DVD studio pro is encoded in the plist as base64 data that describes the text string along with its formatting. I can't seem to figure out how to understand this data. Ideally, I'd like to be able to alter the text string but not the formatting. The following seems to describe a text box that says "Menu title here". There are two strings, one with the key called "dictionary" and the other called "string"; both are CFData. Any ideas how I can parse this or convert this into a format that I can edit directly? I've been playing around with writing a little converter in cocoa, but no luck yet.
<dict>
<key>Dictionary</key>
<data>
BAtzdHJlYW10
eXBlZIHoA4QB
QISEhAxOU0Rp
Y3Rpb25hcnkA
hIQITlNPYmpl
Y3QAhYQBaQaS
hISECE5TU3Ry
aW5nAZSEASsG
TlNGb250hpKE
hIQGTlNGb250
HpSVJIQFWzM2
Y10GAAAAGgAA
AP/+TAB1AGMA
aQBkAGEARwBy
AGEAbgBkAGUA
AACEAWYVhAFj
AJsBmwCbAIaS
hJaXB05TQ29s
b3KGkoSEhAdO
U0NvbG9yAJSb
AYQEZmZmZoPz
8nI/g/Dvbz+D
7OtrPwGGkoSW
lwtOU0V4cGFu
c2lvboaShISE
CE5TTnVtYmVy
AISEB05TVmFs
dWUAlIQBKoSa
moNHx9c9hpKE
lpcNTlNPYmxp
cXVlbmVzc4aS
hJ6ghIQBZKEA
hpKElpcQTlNQ
YXJhZ3JhcGhT
dHlsZYaShISE
EE5TUGFyYWdy
YXBoU3R5bGUA
lIQEQ0NAUwAA
hQCGkoSWlxFO
U0JhY2tncm91
bmRDb2xvcoaS
hJubA4QCZmYA
AIaG
</data>
<key>String</key>
<data>
BAtzdHJlYW10
eXBlZIHoA4QB
QISEhBJOU0F0
dHJpYnV0ZWRT
dHJpbmcAhIQI
TlNPYmplY3QA
hZKEhIQITlNT
dHJpbmcBlIQB
Kw9OZW51IFRp
dGxlIEhlcmWG
hAJpSQEPkoSE
hAxOU0RpY3Rp
b25hcnkAlIQB
aQWShJaWDU5T
T2JsaXF1ZW5l
c3OGkoSEhAhO
U051bWJlcgCE
hAdOU1ZhbHVl
AJSEASqEhAFk
nQCGkoSWlgtO
U0V4cGFuc2lv
boaShJuchIQB
Zp6DR8fXPYaS
hJaWEE5TUGFy
YWdyYXBoU3R5
bGWGkoSEhBBO
U1BhcmFncmFw
aFN0eWxlAJSE
BENDQFMAAIUA
hpKElpYGTlNG
b250hpKEhIQG
TlNGb250HpSZ
JIQFWzM2Y10G
AAAAGgAAAP/+
TAB1AGMAaQBk
AGEARwByAGEA
bgBkAGUAAACe
FYQBYwCjAaMA
owCGkoSWlgdO
U0NvbG9yhpKE
hIQHTlNDb2xv
cgCUowGEBGZm
ZmaD8/JyP4Pw
728/g+zraz8B
hoaG
</data>
</dict>

That's a base64-coded NSArchiver archive. You need to decode base64 first, then use [NSUnarchiver unarchiveObjectWithData:]. The "Dictionary" entry above looks like this after decoding (in Python syntax because I used pyObjC):
{
NSBackgroundColor = "NSCalibratedWhiteColorSpace 0 0";
NSColor = "NSCalibratedRGBColorSpace 0.94902 0.937255 0.921569 1";
NSExpansion = "0.1053606";
NSFont = "\"LucidaGrande 21.00 pt. P [] (0x103110b60) fobj=0x103110c30, spc=6.64\"";
NSObliqueness = 0;
NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n 28L,\n 56L,\n 84L,\n 112L,\n 140L,\n 168L,\n 196L,\n 224L,\n 252L,\n 280L,\n 308L,\n 336L\n), DefaultTabInterval 0, Blocks (null), Lists (null), BaseWritingDirection -1, HyphenationFactor 0, TighteningFactor 0.05, HeaderLevel 0";
}

Related

MFC: how to set font size?

I am currently using the code below to set font.
CFont my_font;
my_font.CreateFont(86, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Arial"));
void CMyView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
...
CFont *old_font = pDC->SelectObject(&my_font);
...
}
I test using print to PDF. It works ok on my machine using Microsoft Print to PDF. But when I build and run it on another machine using a very old version of Adobe PDF, the font is too small. What is the right way to set font so that its size is consistent across different machines?

Imagick trimImage incomplete results

My results can be seen at http://cwstarkey.com/Capture.PNG
Trim is only removing the top, I would like all the whitespace removed, leaving only the (original scanned) text image. Any ideas?
My code:
$im = new Imagick();
$im->pingImage($imfilename);
$im->readImage($imfilename);
$im->trimImage(0);
$im->setImagePage(0, 0, 0, 0);
$im->writeImage(APP.WEBROOT_DIR.DS.'receipts/'.$date = date('YmdHis').'.jpg');
$im->destroy();

Save the screenshot of an application into a bitmap

I am working on a problem, where in I am trying to save the screenshot of a window(including the title bar and borders) to a PNG file. For certain applications like Google Chrome and Visual Studio, I am not able to get the complete window's image that we get with Alt + PrintScreen.
The issues are:
For Google Chrome, I am not getting the Minimize, Maximize and Close buttons
For Visual Studio, I am getting only certain parts and missing Solution Explorer and Output windows.
I have made sure the handle I use is the root window's handle
Below is the code I use to get the BitMap:
hdc = GetDCEx(hwnd, 0, DCX_WINDOW);
hDest = CreateCompatibleDC (hdc);
GetWindowRect (hwnd, &rt);
hBitmap = CreateCompatibleBitmap (hdc, rt.right - rt.left, rt.bottom - rt.top);
SelectObject(hDest, hBitmap);
BitBlt( hDest, 0, 0, rt.right - rt.left, rt.bottom - rt.top, hdc, 0, 0, SRCCOPY);
Thanks,
Raaja

Win32 API: How to scroll down automatically a text inside EDIT control?

I have an EDIT control created like this:
hwndEDIT_5 = CreateWindowEx (
0, "EDIT", NULL,
WS_VSCROLL | WS_BORDER | WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY,
135, 450, 555, 200,
h2, ( HMENU ) ID_EDIT_CONSOLE,
h1, NULL
);
As you can see it is a read-only EDIT area where multi lines text can be displayed. It is supposed to be a console where I can display some information for users when they use the program. I would like the text area to automatically scroll to the bottom-most entry (the newest one) whenever a new line (or message for an user) is added. I've implemented this:
SetDlgItemText ( h2, ID_EDIT_CONSOLE, ch_s );
SCROLLINFO scr;
SCROLLINFO * scr_p = &scr;
scr.cbSize = sizeof ( SCROLLINFO );
scr.fMask = SIF_RANGE;
GetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, scr_p );
int mmax = scr.nMax;
scr.fMask = SIF_POS;
scr.nPos = mmax;
SetScrollInfo ( GetDlgItem ( h2, ID_EDIT_CONSOLE), SB_VERT, scr_p, TRUE );
That code is scrolling vertical scrollbar to the end of an EDIT control after adding new msg and it works great, the scrollbar gets scrolled but the text still remains visible from the beginning - it rewinds to the beginning after addition while scrollbar rewinds to the bottom. How to make it properly?
Last but not least - this is might be important - in order to display a message firstly I capture the text that is already displayed by using:
GetDlgItemText ( h2, ID_EDIT_CONSOLE, buf, len + 1 );
then I convert buf into string and add to that string a new message that I want to display. Then I convert it back to char array and set it up with SetDlgItemText. I seperate lines by using \r\n. I've coded it that way because I didn't know how to add a line to an EDIT control in different way than using SetDlgItemText. And it adds only one entry AFAIK - if used twice I will not come up with two entries added to an EDIT control, but the first one will get replaced by second function call.
Don't use SetScrollInfo. Use SendMessage() with the EM_LINESCROLL message, sending the message to the edit control's window handle.
SendMessage(MemoHwnd, EM_LINESCROLL, 0, NumLinesToScroll);
The documentation says:
The control does not scroll vertically past the last line of text in the edit control. If the current line plus the number of lines specified by the lParam parameter exceeds the total number of lines in the edit control, the value is adjusted so that the last line of the edit control is scrolled to the top of the edit-control window.
I had the same problem and solved it with Jerry Coffin's answer and some research.
This is the way I use now:
string text = "Append this text";
SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos
SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)(text.c_str())); //append text to current pos and scroll down
If needed: To scroll at the end of Edit Control without appending text:
SendMessageA(hEdit, EM_SETSEL, 0, -1); //Select all.
SendMessageA(hEdit, EM_SETSEL, -1, -1);//Unselect and stay at the end pos
SendMessageA(hEdit, EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos
You can add text by setting the beginning and end of the selection to the end of the text in the control (EM_SETSEL), then replacing the (empty) selection with your new text (EM_REPLACESEL).
Scrolling to the bottom can be done with EM_SCROLLCARET after the caret (the selection) is at the end of the text. There are other ways, but if you're doing it immediately after adding text, this is probably the easiest.
in my case I had a multi line string and Ken White's idea worked very well:
HWND hEdit = this->GetDlgItem(IDC_EDIT_LOG)->m_hWnd;
if (hEdit)
{
int lineCount = m_strClientLog.Replace(_T("\n"), _T("\n"));
::SendMessage(hEdit, EM_LINESCROLL, 0, lineCount);
}
for MFC projects you can use:
mLoggingTextCtl.SendMessage(EM_SETSEL, 0, -1); //Select all.
mLoggingTextCtl.SendMessage(EM_SETSEL, -1, -1);//Unselect and stay at the end pos
mLoggingTextCtl.SendMessage(EM_SCROLLCARET, 0, 0); //Set scrollcaret to the current Pos

Color change in Rich Edit Control

when you erase a coloured text. By default, the control sets the new entered text colour back to that was recently erased. how can you avoid that? do you need to check each character style before you type?
UPDATE:
I'm trying to set the text color like this.
SendMessage(hEdit, EM_SETSEL, start_pos, end_pos); //select text for coloring
CHARFORMAT cf;
memset( &cf, 0, sizeof cf );
cf.cbSize = sizeof cf;
cf.dwMask = CFM_COLOR;
cf.crTextColor = RGB(255,0,0);
SendMessage( hEdit , EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);
SendMessage(hEdit, EM_SETSEL, -1, 0 ); //deselect text
cf.crTextColor = RGB(0,0,0); //reset colour
SendMessage( hEdit , EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf); //set colour
Your question is quite unclear. Wild stab at it: you lose all formatting when you assign the Text property. Be sure to use AppendText() instead. And to set the SelectionColor and SelectionBackColor properties back to what it was after colorizing any text so that newly entered text gets the preferred default colors.

Resources