MS Office Forum / Word / Programming / May 2006
Modify or Add to Color Palette
|
|
Thread rating:  |
Greg Maxey - 24 May 2006 12:19 GMT Is there any way to modify or add to the 48 colors available to the "backcolor" property of a control?. I am playing around with a Userform to create a tool for shading text and I want to match the color of the control label with the virtually limitless shades of color I can create with text shading.
http://gregmaxey.mvps.org/Highlighter.htm
If I record a macro applying a custom color the result is an 8 digit number
.BackgroundPatternColor = 16715142
I can also use RBG values
.BackgroundPatternColor = RBG(255, 0, 00)
or constants
.BackgroundPatternColor = wdColorRed
The control backcolor property color definition appears to be some sort of Hex number.
Does anyone know if these colors can be changed and if so how to convert one of the constructions above to the type number the control uses? Thanks.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
Jonathan West - 24 May 2006 13:42 GMT Hi Greg,
The background pattern colour is a Long value, which is either
- A positive number representing an RGB code, or - A negative number representing a theme color, such as "Menu Text" or "Active Title Bar Text"
These negative numbers will give you different colors depending on the Windows theme you currently have set up. Set the caption of a form to "Active Title Bar Text" and it will be white in the normal Windows XP theme. If you go to Display Properties in Windows, click the Appearance tab on the dialog and set the color scheme to Silver, you will then find that text set to "Active Title Bar Text" will now be black, even though you have made no change in your code.
Tbe Word color constants are simply selected RGB codes provided to make it easier to remember and use the basic colors.
As far as I'm aware, there are no predefined constants for the theme colors. But you can find out the values by selecting a control and clicking on the dropdown button against the BackColor property in the Properties window. The color is shown in hex, for instance Button Face is &H8000000F&. If you open the Immediate window and type this
? &H8000000F&
and press Enter, you will get the decimal equivalent for that hex value, which is -2147483633. You can use either the hex or decimal version of the number in your VBA code.
 Signature Regards Jonathan West - Word MVP www.intelligentdocuments.co.uk Please reply to the newsgroup Keep your VBA code safe, sign the ClassicVB petition www.classicvb.org
Is there any way to modify or add to the 48 colors available to the "backcolor" property of a control?. I am playing around with a Userform to create a tool for shading text and I want to match the color of the control label with the virtually limitless shades of color I can create with text shading.
http://gregmaxey.mvps.org/Highlighter.htm
If I record a macro applying a custom color the result is an 8 digit number
.BackgroundPatternColor = 16715142
I can also use RBG values
.BackgroundPatternColor = RBG(255, 0, 00)
or constants
.BackgroundPatternColor = wdColorRed
The control backcolor property color definition appears to be some sort of Hex number.
Does anyone know if these colors can be changed and if so how to convert one of the constructions above to the type number the control uses? Thanks.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
Greg Maxey - 24 May 2006 15:02 GMT Jonathan,
Thanks for the information, but I am not sure that I see the answer I am looking for. This could very well be because I didn't state the question clearly.
I want to:
1. Create a shading color that I like using Format>Borders and Shading>Shading>More Colors>Custom. 2. Apply that color to a selection of text by clicking on a label control in a Userform
I have step 1 and 2 figured out. Now
3. Apply that exact same color as the backcolor property of the control.
I don't know if you took a look at the link in my question or not. Basically I want the label to look like the highlight color choice. If the shading looks like burnt orange I want the label to look like burnt orange.
How do convert the shading.backgroundPatternColor (either the RBG values or the 8 digit values) to the format used by the Backcolor property of the control?
Jay Freedman - 24 May 2006 16:19 GMT Hi Greg,
If you have the color as a Long value, you can just set Me.BackColor equal to that value.
If you have the separate R, G, and B values, you can get the Long value with
nColor = ((B * 256) + G) * 256 + R
Here's some old code that does the reverse calculation. The userform just has two buttons on it, CommandButton1 that says "Choose Color" and CommandButton2 that says "Quit". It uses the built-in Windows color picker dialog to select a color.
Private Type CHOOSECOLOR lStructSize As Long hwndOwner As Long hInstance As Long rgbResult As Long lpCustColors As String Flags As Long lCustData As Long lpfnHook As Long lpTemplateName As String End Type
Dim CustomColors() As Byte
Private Declare Function ChooseColorAPI Lib "comdlg32.dll" Alias _ "ChooseColorA" (pChoosecolor As CHOOSECOLOR) As Long
Private Declare Function FindWindow Lib "user32" _ Alias "FindWindowA" (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long
Private Function GetWinwordHwnd() As Long Dim hWnd As Long
hWnd = FindWindow("opusApp", vbNullString) GetWinwordHwnd = hWnd End Function
Private Sub CommandButton2_Click() Unload Me End Sub
Private Sub CommandButton1_Click() Dim cc As CHOOSECOLOR Dim lReturn As Long, Rval As Long Dim Gval As Long, Bval As Long Dim i As Integer
cc.lStructSize = Len(cc) cc.hwndOwner = GetWinwordHwnd() cc.hInstance = 0 cc.lpCustColors = StrConv(CustomColors, vbUnicode) cc.Flags = 0
' call the color picker lReturn = ChooseColorAPI(cc) If lReturn <> 0 Then ' extract the color values Rval = cc.rgbResult Mod 256 Bval = Int(cc.rgbResult / 65536) Gval = Int((cc.rgbResult - (Bval * 65536) - Rval) / 256)
' display the values in the dialog title bar Me.Caption = "RGB Value User Chose: R=" & Str$(Rval) & _ " G=" & Str$(Gval) & " B=" & Str$(Bval) ' change the dialog background to that color Me.BackColor = cc.rgbResult
' save the color values to send to the ' color picker for the next iteration CustomColors = StrConv(cc.lpCustColors, vbFromUnicode) ReDim CustomColors(0 To 16 * 4 - 1) As Byte For i = LBound(CustomColors) To UBound(CustomColors) CustomColors(i) = 0 Next i Else MsgBox "User chose the Cancel Button" End If End Sub
Private Sub UserForm_Load() ReDim CustomColors(0 To 16 * 4 - 1) As Byte Dim i As Integer
For i = LBound(CustomColors) To UBound(CustomColors) CustomColors(i) = 0 Next i End Sub
Private Sub UserForm_Layout() Me.Move 150, 100 End Sub
 Signature Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
> Jonathan, > [quoted text clipped - 22 lines] > values or the 8 digit values) to the format used by the Backcolor > property of the control? Greg Maxey - 24 May 2006 16:39 GMT Thanks Jay. I think I can make this work.
Greg Maxey - 24 May 2006 16:47 GMT Thanks Jay,
I will see if I can work through this an apply it to my project.
Greg Maxey - 24 May 2006 17:15 GMT Jay,
Sorry for the multiple posts. The server was timing out and I didn't think my first reply posted.
That is a neat bit of code (your work?). Smart guy or gal whoever it was. Actually, for my current purpose it appears that I can just use constants when available and convert the RBG values without the formula:
Private Sub UserForm_Initialize() Me.Label1.BackColor = wdColorLightYellow Me.Label2.BackColor = wdColorLightGreen Me.Label3.BackColor = wdColorLightTurquoise Me.Label4.BackColor = wdColorRose Me.Label5.BackColor = CLng(RGB(255, 120, 116)) Me.Label6.BackColor = wdColorPaleBlue Me.Label7.BackColor = wdColorTan Me.Label8.BackColor = wdColorGray10 End Sub
Thanks for nudging me to what now appears obvious. The initialize event seems the obvious place to set backcolor.
Karl E. Peterson - 24 May 2006 17:45 GMT > If you have the separate R, G, and B values, you can get the Long > value with > > nColor = ((B * 256) + G) * 256 + R Uh, why not just:
nColor = RGB(R, G, B)
Totally avoids the potential issue of intermediate Overflow with the math above.
 Signature Working without a .NET? http://classicvb.org/
Jay Freedman - 25 May 2006 03:15 GMT Why not? Because I don't work with colors often enough to remember that there is an RGB function? :-)
>> If you have the separate R, G, and B values, you can get the Long >> value with [quoted text clipped - 7 lines] >Totally avoids the potential issue of intermediate Overflow with the math >above. -- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
Karl E. Peterson - 25 May 2006 18:46 GMT >>> If you have the separate R, G, and B values, you can get the Long >>> value with [quoted text clipped - 7 lines] > Why not? Because I don't work with colors often enough to remember > that there is an RGB function? :-) But you _do_ remember that formula??? ;-)
On a more serious note, if the R/G/B variables are defined As Integer, you're pretty likely to generate Overflow errors with that math, right? That confuses the heck out of a lot of newbs, hence my posting to the thread for future googlers.
Public Function ShadesOfGray() As OLE_COLOR Dim nColor As Long, r As Integer, g As Integer, b As Integer r = 128: g = 128: b = 128 nColor = ((b * 256) + g) * 256 + r End Function
The problem is, VB stores the intermediate result(s) in the "smallest" variable type indicated by the types of variables used in the equation. In this case, in an Integer. Boom!
If using the formula is required, it's easily fixed with something like this:
nColor = ((CLng(b) * 256) + g) * 256 + r
Fwiw...
 Signature Working without a .NET? http://classicvb.org/
Jay Freedman - 27 May 2006 03:14 GMT >>>> If you have the separate R, G, and B values, you can get the Long >>>> value with [quoted text clipped - 9 lines] > >But you _do_ remember that formula??? ;-) No, I don't _remember_ it, I looked it up, just like I do with everything that runs through my steel sieve of a memory. :-) I would have looked up the RGB function, but... I forgot.
>On a more serious note, if the R/G/B variables are defined As Integer, >you're pretty likely to generate Overflow errors with that math, right? [quoted text clipped - 17 lines] > >Fwiw... True, but I wouldn't run into that problem because I always use Long instead of Integer for all fixed-point variables. VBA integers are stored in 32-bit locations anyway, so declaring an Integer just wastes time in implicit conversions, not to mention the possibility of overflow errors.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
Karl E. Peterson - 30 May 2006 23:08 GMT >>>>> If you have the separate R, G, and B values, you can get the Long >>>>> value with [quoted text clipped - 12 lines] > No, I don't _remember_ it, I looked it up, just like I do with > everything that runs through my steel sieve of a memory. :-) Here's an easier one to remember, if you like that sort of thing... <g>
nColor = b * &h10000 + g * &h100 + r
> I would have looked up the RGB function, but... I forgot. <bg>
>> On a more serious note, if the R/G/B variables are defined As >> Integer, you're pretty likely to generate Overflow errors with that [quoted text clipped - 23 lines] > time in implicit conversions, not to mention the possibility of > overflow errors. True. (me too)
 Signature Working without a .NET? http://classicvb.org/
Greg Maxey - 24 May 2006 18:08 GMT Jay,
I have stepped through this rather lengthy routine several times and have a few questions. It appears that if you define a custom color then that color is saved and the next time the picker is called you should see that color as a custom color. This seems erratic at best and I never see a sitation when:
Private Sub UserForm_Load() ReDim CustomColors(0 To 16 * 4 - 1) As Byte Dim i As Integer For i = LBound(CustomColors) To UBound(CustomColors) CustomColors(i) = 0 Next i End Sub
Is called or performed.
Am I missing something?
Jonathan West - 24 May 2006 20:21 GMT That should be UserForm_Initialize() not UserForm_Load()
Somebody hasn't been thorough about doing a conversion from VB6, where forms have a Form_Load() event
 Signature Regards Jonathan West - Word MVP www.intelligentdocuments.co.uk Please reply to the newsgroup Keep your VBA code safe, sign the ClassicVB petition www.classicvb.org
> Jay, > [quoted text clipped - 15 lines] > > Am I missing something? Greg Maxey - 24 May 2006 20:37 GMT Jonathan,
OK, I moved the Load code to an Initialize envent.
Still, when the color dialog box is displayed the custom colors all appear as black even after setting specific custom colors in earlier iterations.
It appears as thoough the code is meant to save custom colors created and then display them as a custom color when the color dialog box is displayed the next time around.
Jonathan West - 24 May 2006 20:59 GMT > Jonathan, > [quoted text clipped - 7 lines] > and then display them as a custom color when the color dialog box is > displayed the next time around. Where is the original declaration of the CustomColors() array?
 Signature Regards Jonathan West - Word MVP www.intelligentdocuments.co.uk Please reply to the newsgroup Keep your VBA code safe, sign the ClassicVB petition www.classicvb.org
Greg Maxey - 24 May 2006 21:21 GMT Jonathan,
I copied the code as Jay Freedman posted earlier in this thread (or string whatever they are called). It appears to be declared at the module level:
Private Type CHOOSECOLOR lStructSize As Long hwndOwner As Long hInstance As Long rgbResult As Long lpCustColors As String Flags As Long lCustData As Long lpfnHook As Long lpTemplateName As String End Type
Dim CustomColors() As Byte
Private Declare Function ChooseColorAPI Lib "comdlg32.dll" Alias _ "ChooseColorA" (pChoosecolor As CHOOSECOLOR) As Long
Jay Freedman - 25 May 2006 03:26 GMT No, I think I'm missing something. Like I said, it's old code, maybe 10 years or so, ported from VB6 (and not well, as Jonathan noted), and probably messed with along the way. I've long since forgotten where I got the original pieces. I grabbed the macro out of my "junk drawer" template, and ran it just before I posted to make sure it didn't fall over, but I didn't check out the custom color storage part.
The problem is in the Click procedure in the lines
' save the color values to send to the ' color picker for the next iteration CustomColors = StrConv(cc.lpCustColors, vbFromUnicode) ReDim CustomColors(0 To 16 * 4 - 1) As Byte For i = LBound(CustomColors) To UBound(CustomColors) CustomColors(i) = 0 Next i
Just delete the ReDim and the For...Next loop -- that's what's setting the custom colors back to all black (RGB = 0,0,0).
And as Jonathan says, rename the Load routine to UserForm_Initialize.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
>Jay, > [quoted text clipped - 15 lines] > >Am I missing something? Greg Maxey - 25 May 2006 03:37 GMT Jay, that certainly improves matters.
Thanks.
 Signature Greg Maxey/Word MVP See: http://gregmaxey.mvps.org/word_tips.htm For some helpful tips using Word.
> No, I think I'm missing something. Like I said, it's old code, maybe > 10 years or so, ported from VB6 (and not well, as Jonathan noted), and [quoted text clipped - 37 lines] >> >> Am I missing something?
|
|
|