Prev: API-Guide
Next: Find Addin
From: Bee on 5 Apr 2010 19:19 And so it begs the question, how do I set the margins without making it "permanent"? In one case I don't care since it is for display only. Your sub is perfect for that. In another case, the user edits the document and saves and reloads it later, maybe many times. I am assuming that in order to use the justification, I need to set the non-permanent margins through the SendMessage or can I just use the standard RTB margin settings? So for now I can set the margins to 0 thru your sub. "Mike Williams" wrote: > "Bee" <Bee(a)discussions.microsoft.com> wrote in message > news:890253D9-9F9D-4F2F-946A-97672070B740(a)microsoft.com... > > > Your code example WORKS PERFECTLY! > > You're welcome. By the way, I used full justification in order that you > could easily see the right edge of the text from any point in your document > so that you could easily see whether your problem had been solved or not. > You can of course change that to left justification or whatever else you > wish. Also, and this is particularly important, I used a left and right > paragraph indent of 50 pixels for all paragraphs in the document, again in > order that you could easily see the results. Setting paragraph indents for > the whole document in this way is not what you would normally want to do > (there are other ways of setting "display" margins in the RTB if that is > what you need to do). The reason I say that it is not normally wise to do it > in the way I have done in the example is because if you save the document as > rtf using RTB.SaveFile then those 50 pixel left and right indents (0.521 > inches on a computer running at the standard 96 dpi setting) will be part of > the rtf document itself (rather than merely an effect of the visible RTB > display) and therefore when you load the saved document into a word > processor then those left and right indents of 0.521 inches will effecively > be "added to" the standard default left and right page margins of your word > processor. In other words, if your copy of Micro$oft Word or whatever > normally uses a 1 inch left and right margin (as is typical in the UK) then > you will end up with apparent 1.521 inch left and right margins (0.521 > inches of which are actually paragraph indents). This is fine if that is > what you want, but it is not the normal requirement. Setting left and right > paragraph indents in the way that I have done in the code I posted is > normally what you would do to just one or two (or more) paragraphs of a > document when you specifically want those paragraphs to be indented in at > either side, differently from the rest of the paragraphs in the document. I > just thought I would mention that point for completeness. > > Mike > > > . >
From: Mike Williams on 6 Apr 2010 10:10 "Bee" <Bee(a)discussions.microsoft.com> wrote in message news:1F5258D6-152F-4576-9D94-DC896C76E04E(a)microsoft.com... > And so it begs the question, how do I set the margins > without making it "permanent" [1]? Before I answer that question let me just say something about the code I posted yesterday. If you run the code and click the button then it will fully justify the contents of the RTB and it will set up the desired left and right paragraph indents for the entire document. However, with the code as it currently stands, if you click the button twice you will find that it increases the left indent (instead of simply setting it to the same value) and each time you click the button the left indent will get bigger. That is because I had inadvertently used the wrong constant. I had used PFM_OFFSETINDENT, which is a relative adjustment to the left indent, whereas I should have used PFM_STARTINDENT, which is an absolute left indent. So, in order to fix that problem add the following to your declarations: Private Const PFM_STARTINDENT As Long = &H1 .. . and change the mask line in the example code to: PF2.dwMask = PFM_ALIGNMENT Or PFM_OFFSET _ Or PFM_STARTINDENT Or PFM_RIGHTINDENT In fact I used the EM_SETPARAFORMAT method so that I could use ADVANCEDTYPOGRAPHY in order to set full justification, something which cannot be done using native RTB properties or methods and I included the indent settings in that method merely because I was using it anyway to set full justification. If you do not want to set full justification and you do not want to do anything else that cannot be done with the native VB methods then you can simply use the RTB SelIndent and SelRightIndent and SelHangingIndent properties to set your indents, instead of the EM_SETPARAFORMAT code. > And so it begs the question, how do I set the margins > without making it "permanent" [2]? As you will now be aware, the indents mentioned above apply to the rtf document itself (either to all its paragraphs or to just some of its paragraphs, whichever you desire) and as such they will be part of the rtf document when it is saved from your RTB. So, if you set those indents and the user edits and saves the document and then later loads it back (into either an RTB or Micros$oft Word or whatever) then the indents will still be there in the document. Presumably, that is what you mean by "permanent". The above of course is often exactly what you want to do, but if you do not want to do that and if you want to set up "margins" purely so as to adjust the way your RTB displays the document (without them becoming part of the document itself) then you need to do it a different way. The RTB has a RightMargin property which is for that precise purpose. When you set the RTB.RightMargin then the RTB will display your document with the specified margin as the user sees it in the RTB, but the margin will not actually become part of the document. The problem is that the RTB does not have an equiavlent LeftMargin property, so you need to find a different way of causing the RTB to display a left margin that is not actually part of the document. There are a number of ways of doing that: One way of course would be to set the left and right indents for the entire document (as the code I posted yesterday does) and then allow your user to edit the document in the RTB and then when you come to finally save the edited document you can simply use the same code, but this time to set the left and right indents back to zero again before you save it. Another way is to use a PictureBox with a white background as the container for the RTB. If you set the RTB's Appearance property to rtfFlat and its BorderStyle to rtfNoBorder and if you adjust the RTB's size so that it is the same height as the client area of the pictureBox but not quite as wide then you can position it within the pictureBox to give the appearance of whatever left and right margins you desire. There are some problems associated with that method because of the fact that a click in the "border area" will actually be a click in the PictureBox, but with suitable code you can take care of those problems. One other way would be to send the RTB an EM_SETMARGINS message. That specific message was really only useful in standard TextBoxes and it failed to work properly in RichtextBoxes, but I've noticed in recent years that it seems to work okay on RTBs. I definitely remember it not working for many years. Perhaps recent incarnations of the RichTextBox have overcome that problem? Anyway, it certainly works for me on my current system. I've tried a number of different ways to "break it" and it still seems to work. For what it's worth you can give it a try. Perhaps others here will confirm whether it works or not on their own systems, and whether they can "break it" by doing certain things? It seems odd that it works now whereas it did not work properly before without any kind of official comment appearing anywhere. So, you can use any one of the above methods, and perhaps others here will have other methods that can be used. For what it's worth, here is some code for the EM_SETMARGINS method: Mike Option Explicit Private Declare Function SendMessage Lib "user32" Alias _ "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Private Const EM_SETMARGINS As Long = &HD3 Private Const EC_LEFTMARGIN As Long = &H1 Private Const EC_RIGHTMARGIN As Long = &H2 Private Sub Command1_Click() Dim leftmargin As Long, rightmargin As Long, margins As Long leftmargin = 50 ' pixels from left of RTB to left of text rightmargin = 50 ' pixels from tight of RTB to right of text margins = leftmargin + rightmargin * &H10000 SendMessage RichTextBox1.hwnd, EM_SETMARGINS, _ EC_LEFTMARGIN Or EC_RIGHTMARGIN, _ ByVal margins End Sub
From: Horst Heinrich Dittgens on 7 Apr 2010 11:22 Don't know why there is so much discussion about wordwrapping, it's clearly written out in the VB6 help file. Use RightMargin property to control wordwrapping. This value indicates the difference in twips between the right border of the displayed wordwrapped text and the right border of RichTextBox control, so a value of zero will always break at the control's right border, and a value of, f.e., 999999 will set the breakpoint far enough outside the right border so that no line should be broken and only CRs will do. For precise calculations where wordwrapping is done you might have to take into account the control's border width (eventually as well as the width of a vertical scroll bar) . A simple form with a RTB having some text loaded will easily show it. In my projects I only use values of zero and 999999, but if I do remember right then I once had to use a negative value to move the wordwrap to the left into the visible area.
From: Mike Williams on 7 Apr 2010 14:11 "Horst Heinrich Dittgens" <hhd71(a)sofort-mail.de> wrote in message news:hpi83f$gg9$02$1(a)news.t-online.com... > Don't know why there is so much discussion > about wordwrapping . . . Perhaps it is because many people, such as yourself for example, do not undertsand it. > Use RightMargin property to control wordwrapping. This > value indicates the difference in twips . . Wrong. > . . between the right border of the displayed wordwrapped text and the > right border of RichTextBox control Wrong again! > For precise calculations where wordwrapping is done you > might have to take into account the control's border width Well, for precise wrapping the very first thing you need to take into account is the basics of how it works, and you clearly do not understand that yet. In any case, the subject was not just about word wrapping, which is perhaps just as well because if you had answered it yourself then you would have given the OP all the wrong information. It was about a problem the OP was having when his rtf was failing to wrap as he expected it to even after he had set the Rightmargin to the appropriate value, and it was in fact more to do with certain paragraph indents in his rtf that needed correcting. Mike
From: Bee on 7 Apr 2010 18:44
This will help with future work. And I will incorporate your sage advice. I my initial case, the text is only loaded once and therefore the relative vs absolute issue did not show up. But I will fix that and now know better. Thanks again Mike. "Mike Williams" wrote: > "Bee" <Bee(a)discussions.microsoft.com> wrote in message > news:1F5258D6-152F-4576-9D94-DC896C76E04E(a)microsoft.com... > > > And so it begs the question, how do I set the margins > > without making it "permanent" [1]? > > Before I answer that question let me just say something about the code I > posted yesterday. If you run the code and click the button then it will > fully justify the contents of the RTB and it will set up the desired left > and right paragraph indents for the entire document. However, with the code > as it currently stands, if you click the button twice you will find that it > increases the left indent (instead of simply setting it to the same value) > and each time you click the button the left indent will get bigger. That is > because I had inadvertently used the wrong constant. I had used > PFM_OFFSETINDENT, which is a relative adjustment to the left indent, whereas > I should have used PFM_STARTINDENT, which is an absolute left indent. So, in > order to fix that problem add the following to your declarations: > > Private Const PFM_STARTINDENT As Long = &H1 > > .. . and change the mask line in the example code to: > > PF2.dwMask = PFM_ALIGNMENT Or PFM_OFFSET _ > Or PFM_STARTINDENT Or PFM_RIGHTINDENT > > In fact I used the EM_SETPARAFORMAT method so that I could use > ADVANCEDTYPOGRAPHY in order to set full justification, something which > cannot be done using native RTB properties or methods and I included the > indent settings in that method merely because I was using it anyway to set > full justification. If you do not want to set full justification and you do > not want to do anything else that cannot be done with the native VB methods > then you can simply use the RTB SelIndent and SelRightIndent and > SelHangingIndent properties to set your indents, instead of the > EM_SETPARAFORMAT code. > > > And so it begs the question, how do I set the margins > > without making it "permanent" [2]? > > As you will now be aware, the indents mentioned above apply to the rtf > document itself (either to all its paragraphs or to just some of its > paragraphs, whichever you desire) and as such they will be part of the rtf > document when it is saved from your RTB. So, if you set those indents and > the user edits and saves the document and then later loads it back (into > either an RTB or Micros$oft Word or whatever) then the indents will still be > there in the document. Presumably, that is what you mean by "permanent". > > The above of course is often exactly what you want to do, but if you do not > want to do that and if you want to set up "margins" purely so as to adjust > the way your RTB displays the document (without them becoming part of the > document itself) then you need to do it a different way. The RTB has a > RightMargin property which is for that precise purpose. When you set the > RTB.RightMargin then the RTB will display your document with the specified > margin as the user sees it in the RTB, but the margin will not actually > become part of the document. The problem is that the RTB does not have an > equiavlent LeftMargin property, so you need to find a different way of > causing the RTB to display a left margin that is not actually part of the > document. There are a number of ways of doing that: > > One way of course would be to set the left and right indents for the entire > document (as the code I posted yesterday does) and then allow your user to > edit the document in the RTB and then when you come to finally save the > edited document you can simply use the same code, but this time to set the > left and right indents back to zero again before you save it. > > Another way is to use a PictureBox with a white background as the container > for the RTB. If you set the RTB's Appearance property to rtfFlat and its > BorderStyle to rtfNoBorder and if you adjust the RTB's size so that it is > the same height as the client area of the pictureBox but not quite as wide > then you can position it within the pictureBox to give the appearance of > whatever left and right margins you desire. There are some problems > associated with that method because of the fact that a click in the "border > area" will actually be a click in the PictureBox, but with suitable code you > can take care of those problems. > > One other way would be to send the RTB an EM_SETMARGINS message. That > specific message was really only useful in standard TextBoxes and it failed > to work properly in RichtextBoxes, but I've noticed in recent years that it > seems to work okay on RTBs. I definitely remember it not working for many > years. Perhaps recent incarnations of the RichTextBox have overcome that > problem? Anyway, it certainly works for me on my current system. I've tried > a number of different ways to "break it" and it still seems to work. For > what it's worth you can give it a try. Perhaps others here will confirm > whether it works or not on their own systems, and whether they can "break > it" by doing certain things? It seems odd that it works now whereas it did > not work properly before without any kind of official comment appearing > anywhere. > > So, you can use any one of the above methods, and perhaps others here will > have other methods that can be used. For what it's worth, here is some code > for the EM_SETMARGINS method: > > Mike > > Option Explicit > Private Declare Function SendMessage Lib "user32" Alias _ > "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _ > ByVal wParam As Long, lParam As Any) As Long > Private Const EM_SETMARGINS As Long = &HD3 > Private Const EC_LEFTMARGIN As Long = &H1 > Private Const EC_RIGHTMARGIN As Long = &H2 > > Private Sub Command1_Click() > Dim leftmargin As Long, rightmargin As Long, margins As Long > leftmargin = 50 ' pixels from left of RTB to left of text > rightmargin = 50 ' pixels from tight of RTB to right of text > margins = leftmargin + rightmargin * &H10000 > SendMessage RichTextBox1.hwnd, EM_SETMARGINS, _ > EC_LEFTMARGIN Or EC_RIGHTMARGIN, _ > ByVal margins > End Sub > > > > > . > |